blob: 1c91febd4c64f723108ed24d6501a82be55fe9f5 [file] [log] [blame]
Brian Swetland9c4c0752009-01-25 16:23:50 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
4 *
Rahul Shaharee7baede2021-02-02 13:23:57 +05305 * Copyright (c) 2009-2021, 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"
tracychui792d2ad2020-06-15 10:50:49 +080098#include <mmu.h>
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -070099
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700100extern bool target_use_signed_kernel(void);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700101extern void platform_uninit(void);
Channagoud Kadabi33defe22013-06-18 18:35:40 -0700102extern void target_uninit(void);
Joonwoo Park61112782013-10-02 19:50:39 -0700103extern int get_target_boot_params(const char *cmdline, const char *part,
vijay kumar870515d2015-08-31 16:37:24 +0530104 char **buf);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700105
Sridhar Parasuram7e16d172015-07-05 11:35:23 -0700106void *info_buf;
tracychui9d60fc52020-06-05 17:31:38 +0800107#if defined(ENABLE_PRODINFO_ACCESS)
108void *prodinfo_buf;
109#endif
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700110void write_device_info_mmc(device_info *dev);
111void write_device_info_flash(device_info *dev);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -0700112static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size);
Channagoud Kadabiad259832015-05-29 11:14:17 -0700113static int aboot_frp_unlock(char *pname, void *data, unsigned sz);
Kishor PK38ed93d2017-04-25 14:19:26 +0530114static inline uint64_t validate_partition_size();
Parth Dixit54ac3bb2017-03-07 15:52:48 +0530115bool pwr_key_is_pressed = false;
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530116static bool is_systemd_present=false;
Mayank Grover351a75e2017-05-30 20:06:08 +0530117static void publish_getvar_multislot_vars();
Sridhar Parasurame94e8152014-10-24 14:06:03 -0700118/* fastboot command function pointer */
119typedef void (*fastboot_cmd_fn) (const char *, void *, unsigned);
Monika Singh292b3e92018-03-17 22:40:23 +0530120bool get_perm_attr_status();
tracychui9d60fc52020-06-05 17:31:38 +0800121#if defined(ENABLE_PRODINFO_ACCESS)
122void write_prod_info(prod_info *dev);
123#endif
Sridhar Parasurame94e8152014-10-24 14:06:03 -0700124
125struct fastboot_cmd_desc {
126 char * name;
127 fastboot_cmd_fn cb;
128};
129
Subbaraman Narayanamurthyeb92bcc2010-07-20 14:32:46 -0700130#define EXPAND(NAME) #NAME
131#define TARGET(NAME) EXPAND(NAME)
Brian Swetland2defe162009-08-18 14:35:59 -0700132
Ajay Singh Parmara7865a82015-04-16 21:27:52 -0700133#define DISPLAY_PANEL_HDMI "hdmi"
134
Ajay Dudanicd01f9b2010-02-23 21:13:04 -0800135#ifdef MEMBASE
136#define EMMC_BOOT_IMG_HEADER_ADDR (0xFF000+(MEMBASE))
137#else
David Ng183a7422009-12-07 14:55:21 -0800138#define EMMC_BOOT_IMG_HEADER_ADDR 0xFF000
Ajay Dudanicd01f9b2010-02-23 21:13:04 -0800139#endif
140
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700141#ifndef MEMSIZE
142#define MEMSIZE 1024*1024
143#endif
144
145#define MAX_TAGS_SIZE 1024
Kishor PKee5c0a32018-03-06 16:49:46 +0530146#define PLL_CODES_OFFSET 4096
Kun Liang2f1601a2013-08-12 16:29:54 +0800147/* make 4096 as default size to ensure EFS,EXT4's erasing */
148#define DEFAULT_ERASE_SIZE 4096
Ujwal Patelc0b0a252015-08-16 14:05:35 -0700149#define MAX_PANEL_BUF_SIZE 196
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +0530150#define FOOTER_SIZE 16384
Kun Liang2f1601a2013-08-12 16:29:54 +0800151
Dhaval Patelf83d73b2014-06-23 16:24:37 -0700152#define DISPLAY_DEFAULT_PREFIX "mdss_mdp"
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700153#define BOOT_DEV_MAX_LEN 64
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -0800154
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800155#define IS_ARM64(ptr) (ptr->magic_64 == KERNEL64_HDR_MAGIC) ? true : false
156
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -0700157#define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
158
Ameya Thakur10a33452016-06-13 14:24:26 -0700159//Size of the header that is used in case the boot image has
160//a uncompressed kernel + appended dtb
161#define PATCHED_KERNEL_HEADER_SIZE 20
162
163//String used to determine if the boot image has
164//a uncompressed kernel + appended dtb
165#define PATCHED_KERNEL_MAGIC "UNCOMPRESSED_IMG"
166
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800167#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700168static const char *emmc_cmdline = " androidboot.bootdevice=";
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700169#else
David Ng183a7422009-12-07 14:55:21 -0800170static const char *emmc_cmdline = " androidboot.emmc=true";
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700171#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530172static const char *dynamic_bootdev_cmdline =
173 " androidboot.boot_devices=soc/";
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800174static const char *usb_sn_cmdline = " androidboot.serialno=";
Pavel Nedev328ac822013-04-05 15:25:11 +0300175static const char *androidboot_mode = " androidboot.mode=";
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530176
177static const char *systemd_ffbm_mode = " systemd.unit=ffbm.target";
Matthew Qind886f3c2014-01-17 16:52:01 +0800178static const char *alarmboot_cmdline = " androidboot.alarmboot=true";
Pavel Nedev898298c2013-02-27 12:36:09 -0800179static const char *loglevel = " quiet";
Ajay Dudanica3a33c2011-11-18 08:31:40 -0800180static const char *battchg_pause = " androidboot.mode=charger";
tracychui9d60fc52020-06-05 17:31:38 +0800181#if defined(ENABLE_PRODINFO_ACCESS)
182static const char *cust_sn_cmdline = " androidboot.customer_serialno=";
183static const char *factory_sn_cmdline = " androidboot.factory_serialno=";
184static const char *UsbAdbEnable = " androidboot.adb_enable=1";
185#endif
Shashank Mittalcd98d472011-08-02 14:29:24 -0700186static const char *auth_kernel = " androidboot.authorized_kernel=true";
Pavel Nedev5614d222013-06-17 18:01:02 +0300187static const char *secondary_gpt_enable = " gpt";
Monika Singh292b3e92018-03-17 22:40:23 +0530188#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200189static const char *mdtp_activated_flag = " mdtp";
Monika Singh292b3e92018-03-17 22:40:23 +0530190#endif
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800191static const char *baseband_apq = " androidboot.baseband=apq";
192static const char *baseband_msm = " androidboot.baseband=msm";
193static const char *baseband_csfb = " androidboot.baseband=csfb";
194static const char *baseband_svlte2a = " androidboot.baseband=svlte2a";
Ajay Dudani403bc492011-09-30 16:17:21 -0700195static const char *baseband_mdm = " androidboot.baseband=mdm";
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800196static const char *baseband_mdm2 = " androidboot.baseband=mdm2";
Amol Jadi5c61a952012-05-04 17:05:35 -0700197static const char *baseband_sglte = " androidboot.baseband=sglte";
Amol Jadi2a15a272013-01-22 12:03:36 -0800198static const char *baseband_dsda = " androidboot.baseband=dsda";
199static const char *baseband_dsda2 = " androidboot.baseband=dsda2";
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800200static const char *baseband_sglte2 = " androidboot.baseband=sglte2";
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800201static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1";
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530202static const char *baseband_apq_nowgr = " androidboot.baseband=baseband_apq_nowgr";
Mayank Grover351a75e2017-05-30 20:06:08 +0530203static const char *androidboot_slot_suffix = " androidboot.slot_suffix=";
204static const char *skip_ramfs = " skip_initramfs";
tracychui792d2ad2020-06-15 10:50:49 +0800205static const char *memory_config_3G = " androidboot.memory_config=32GB,3GB";
206static const char *memory_config_4G = " androidboot.memory_config=64GB,4GB";
Mayank Grover466d6562018-05-10 14:52:20 +0530207
208#if HIBERNATION_SUPPORT
209static const char *resume = " resume=/dev/mmcblk0p";
210#endif
211
Sourabh Banerjee6c7153c2018-03-20 01:21:57 +0530212#ifdef INIT_BIN_LE
213static const char *sys_path_cmdline = " rootwait ro init="INIT_BIN_LE;
214#else
Mayank Grover3804be72017-06-22 11:59:23 +0530215static const char *sys_path_cmdline = " rootwait ro init=/init";
Sourabh Banerjee6c7153c2018-03-20 01:21:57 +0530216#endif
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530217
218#if VERITY_LE
219static const char *verity_dev = " root=/dev/dm-0";
220static const char *verity_system_part = " dm=\"system";
221static const char *verity_params = " none ro,0 1 android-verity /dev/mmcblk0p";
222#else
Mayank Grover5384ed82018-05-09 12:09:24 +0530223static const char *sys_path = " root=/dev/mmcblk0p";
lijuang83ef4b22018-08-23 11:01:55 +0800224
225#define MAX_DTBO_IDX_STR 64
226static const char *android_boot_dtbo_idx = " androidboot.dtbo_idx=";
Parth Dixit1375d9e2019-07-08 20:56:13 +0530227
228#define MAX_DTB_IDX_STR MAX_DTBO_IDX_STR
229static const char *android_boot_dtb_idx = " androidboot.dtb_idx=";
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530230#endif
Ajay Dudanid04110c2011-01-17 23:55:07 -0800231
michaellin6be1f392020-04-24 15:05:10 +0800232#include <platform/gpio.h>
233static const char *PCBA_STAGE_0 = " androidboot.pcbastage=EP0";
234static const char *PCBA_STAGE_1 = " androidboot.pcbastage=EP1";
235static const char *PCBA_STAGE_2 = " androidboot.pcbastage=EP2";
236static const char *PCBA_STAGE_3 = " androidboot.pcbastage=FP";
237static const char *PCBA_STAGE_4 = " androidboot.pcbastage=MP";
michaellinaf8857a2020-05-05 14:58:47 +0800238static const char *PCBA_STAGE_5 = " androidboot.pcbastage=MP-8903MB_001";
michaellin6be1f392020-04-24 15:05:10 +0800239static const char *PCBA_STAGE_F = " androidboot.pcbastage=Reserved";
240
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700241#if VERIFIED_BOOT
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700242static const char *verity_mode = " androidboot.veritymode=";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700243static const char *verified_state= " androidboot.verifiedbootstate=";
Parth Dixita5715a02015-10-29 12:25:10 +0530244static const char *keymaster_v1= " androidboot.keymaster=1";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700245//indexed based on enum values, green is 0 by default
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700246
247struct verified_boot_verity_mode vbvm[] =
248{
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700249#if ENABLE_VB_ATTEST
250 {false, "eio"},
251#else
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700252 {false, "logging"},
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700253#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700254 {true, "enforcing"},
255};
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700256struct verified_boot_state_name vbsn[] =
257{
258 {GREEN, "green"},
259 {ORANGE, "orange"},
260 {YELLOW,"yellow"},
261 {RED,"red" },
262};
263#endif
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700264/*As per spec delay wait time before shutdown in Red state*/
265#define DELAY_WAIT 30000
Ashish Bhimanpalliwar8cb34fd2020-11-12 19:26:41 +0530266static unsigned page_size = BOARD_KERNEL_PAGESIZE;
267
268uint32_t kernel_hdr_page_size()
269{
270 return page_size;
271}
272
273
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700274static unsigned page_mask = 0;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +0530275static unsigned mmc_blocksize = 0;
276static unsigned mmc_blocksize_mask = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700277static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
278static bool boot_into_ffbm;
vijay kumar870515d2015-08-31 16:37:24 +0530279static char *target_boot_params = NULL;
Matthew Qind886f3c2014-01-17 16:52:01 +0800280static bool boot_reason_alarm;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -0700281static bool devinfo_present = true;
tracychui9d60fc52020-06-05 17:31:38 +0800282#if defined(ENABLE_PRODINFO_ACCESS)
283static bool prodinfo_present = true;
284#endif
Channagoud Kadabi736c4962015-08-21 11:56:52 -0700285bool boot_into_fastboot = false;
Parth Dixit4097b622016-03-15 14:42:27 +0530286static uint32_t dt_size = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530287static char *vbcmdline;
288static bootinfo info = {0};
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530289static void *recovery_dtbo_buf = NULL;
290static uint32_t recovery_dtbo_size = 0;
291
Shashank Mittalcd98d472011-08-02 14:29:24 -0700292/* Assuming unauthorized kernel image by default */
293static int auth_kernel_img = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530294static device_info device = {DEVICE_MAGIC,0,0,0,0,{0},{0},{0},1,{0},0,{0}};
295
tracychui9d60fc52020-06-05 17:31:38 +0800296#if defined(ENABLE_PRODINFO_ACCESS)
297static prod_info prod = {PRODINFO_MAGIC, {0}, {0}, 0};
298#endif
299
jhchena8a15dd2020-04-24 15:45:57 +0800300#ifdef ENABLE_FUSE_CHECK
301static const char *fuse_blown = " androidboot.oem.color=red";
302static const char *fuse_not_blown = " androidboot.oem.color=brown";
303#endif
304
305#ifdef ENABLE_FUSE_CHECK
306 int is_fused = 0;
307#endif
308
vijay kumarc65876c2015-04-24 13:29:16 +0530309static bool is_allow_unlock = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -0700310
vijay kumarca2e6812015-07-08 20:28:25 +0530311static char frp_ptns[2][8] = {"config","frp"};
312
lijuang511a2b52015-08-14 20:50:51 +0800313static const char *critical_flash_allowed_ptn[] = {
314 "aboot",
315 "rpm",
316 "tz",
317 "sbl",
318 "sdi",
319 "sbl1",
320 "xbl",
321 "hyp",
322 "pmic",
323 "bootloader",
324 "devinfo",
325 "partition"};
326
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +0530327static const char *VirtualAbCriticalPartitions[] = {
328 "misc",
329 "metadata",
330 "userdata"};
331
332static bool CheckVirtualAbCriticalPartition (const char *PartitionName);
333
Rahul Shaharee7baede2021-02-02 13:23:57 +0530334static const char *VabSnapshotMergeStatus[] = {
335 "none",
336 "unknown",
337 "snapshotted",
338 "merging",
339 "cancelled"};
340
Dima Zavin42168f22009-01-30 11:52:22 -0800341struct atag_ptbl_entry
342{
343 char name[16];
344 unsigned offset;
345 unsigned size;
346 unsigned flags;
347};
348
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700349/*
350 * Partition info, required to be published
351 * for fastboot
352 */
353struct getvar_partition_info {
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530354 char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700355 char getvar_size[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for size */
356 char getvar_type[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for type */
357 char size_response[MAX_RSP_SIZE]; /* fastboot response for size */
358 char type_response[MAX_RSP_SIZE]; /* fastboot response for type */
359};
360
361/*
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530362 * Update the part_type_known for known paritions types.
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700363 */
Mayank Groverd38fe012018-03-13 15:33:16 +0530364#define RAW_STR "raw"
Mayank Grover52cd10a2018-03-15 12:57:54 +0530365#define EXT_STR "ext4"
366#define F2FS_STR "f2fs"
367
368#define FS_SUPERBLOCK_OFFSET 0x400
369#define EXT_MAGIC 0xEF53
370#define EXT_MAGIC_OFFSET_SB 0x38
371#define F2FS_MAGIC 0xF2F52010 // F2FS Magic Number
372#define F2FS_MAGIC_OFFSET_SB 0x0
373
374typedef enum fs_signature_type {
375 EXT_FS_SIGNATURE = 1,
376 EXT_F2FS_SIGNATURE = 2,
377 NO_FS = -1
378} fs_signature_type;
379
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530380struct getvar_partition_info part_info[NUM_PARTITIONS];
381struct getvar_partition_info part_type_known[] =
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700382{
Mayank Grover49920212018-02-09 18:15:55 +0530383 { "system" , "partition-size:", "partition-type:", "", "ext4" },
384 { "userdata" , "partition-size:", "partition-type:", "", "ext4" },
385 { "cache" , "partition-size:", "partition-type:", "", "ext4" },
386 { "recoveryfs" , "partition-size:", "partition-type:", "", "ext4" },
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700387};
388
389char max_download_size[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -0700390char charger_screen_enabled[MAX_RSP_SIZE];
tracychui9d60fc52020-06-05 17:31:38 +0800391#if defined(ENABLE_PRODINFO_ACCESS)
392char cust_sn_buf[PRODINFO_MAX_SSN_LEN + 1];
393char factory_sn_buf[PRODINFO_MAX_SSN_LEN + 1];
394char AdbEnable[MAX_RSP_SIZE];
395#endif
396#if defined(ENABLE_PRODINFO_ACCESS)
397char sn_buf[PRODINFO_MAX_ISN_LEN + 1];
398#else
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800399char sn_buf[13];
tracychui9d60fc52020-06-05 17:31:38 +0800400#endif
Dhaval Patel223ec952013-07-18 14:49:44 -0700401char display_panel_buf[MAX_PANEL_BUF_SIZE];
Unnati Gandhi62c8ab82014-01-24 11:01:01 +0530402char panel_display_mode[MAX_RSP_SIZE];
Mayank Grovera64dfbe2018-05-17 14:06:34 +0530403char soc_version_str[MAX_RSP_SIZE];
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530404char block_size_string[MAX_RSP_SIZE];
Rahul Shaharee7baede2021-02-02 13:23:57 +0530405static char SnapshotMergeState[MAX_RSP_SIZE];
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +0530406#if PRODUCT_IOT
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530407
408/* For IOT we are using custom version */
409#define PRODUCT_IOT_VERSION "IOT001"
410char bootloader_version_string[MAX_RSP_SIZE];
411#endif
lijuang102dfa92015-10-09 18:31:03 +0800412
413#if CHECK_BAT_VOLTAGE
lijuang65c5a822015-08-29 16:35:36 +0800414char battery_voltage[MAX_RSP_SIZE];
lijuang102dfa92015-10-09 18:31:03 +0800415char battery_soc_ok [MAX_RSP_SIZE];
416#endif
417
lijuangf16461c2015-08-03 17:09:34 +0800418char get_variant[MAX_RSP_SIZE];
Greg Griscod6250552011-06-29 14:40:23 -0700419
Greg Griscod2471ef2011-07-14 13:00:42 -0700420extern int emmc_recovery_init(void);
421
Kinson Chik0b1c8162011-08-31 16:31:57 -0700422#if NO_KEYPAD_DRIVER
423extern int fastboot_trigger(void);
424#endif
Greg Griscod2471ef2011-07-14 13:00:42 -0700425
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530426static void update_ker_tags_rdisk_addr(boot_img_hdr *hdr, bool is_arm64)
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700427{
428 /* overwrite the destination of specified for the project */
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700429#ifdef ABOOT_IGNORE_BOOT_HEADER_ADDRS
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800430 if (is_arm64)
431 hdr->kernel_addr = ABOOT_FORCE_KERNEL64_ADDR;
432 else
433 hdr->kernel_addr = ABOOT_FORCE_KERNEL_ADDR;
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700434 hdr->ramdisk_addr = ABOOT_FORCE_RAMDISK_ADDR;
435 hdr->tags_addr = ABOOT_FORCE_TAGS_ADDR;
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700436#endif
437}
438
Dima Zavin42168f22009-01-30 11:52:22 -0800439static void ptentry_to_tag(unsigned **ptr, struct ptentry *ptn)
440{
441 struct atag_ptbl_entry atag_ptn;
442
443 memcpy(atag_ptn.name, ptn->name, 16);
444 atag_ptn.name[15] = '\0';
445 atag_ptn.offset = ptn->start;
446 atag_ptn.size = ptn->length;
447 atag_ptn.flags = ptn->flags;
448 memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry));
449 *ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned);
450}
Mayank Grover9df84c02018-08-30 15:46:35 +0530451#ifdef VERIFIED_BOOT_2
452void load_vbmeta_image(void **vbmeta_image_buf, uint32_t *vbmeta_image_sz)
453{
454 int index = 0;
455 char *vbm_img_buf = NULL;
456 unsigned long long ptn = 0;
457 unsigned long long ptn_size = 0;
458
459 /* Immediately return if dtbo is not supported */
460 index = partition_get_index("vbmeta");
461 ptn = partition_get_offset(index);
462 if(!ptn)
463 {
464 dprintf(CRITICAL, "ERROR: vbmeta partition not found.\n");
465 return;
466 }
467
468 ptn_size = partition_get_size(index);
469 if (ptn_size > MAX_SUPPORTED_VBMETA_IMG_BUF)
470 {
471 dprintf(CRITICAL, "ERROR: vbmeta parition size is greater than supported.\n");
472 return;
473 }
474
475 vbm_img_buf = (char *)memalign(CACHE_LINE, ROUNDUP((uint32_t)ptn_size, CACHE_LINE));
476 if (!vbm_img_buf)
477 {
478 dprintf(CRITICAL, "ERROR: vbmeta unable to locate buffer\n");
479 return;
480 }
481
482 mmc_set_lun(partition_get_lun(index));
483 if (mmc_read(ptn, (uint32_t *)vbm_img_buf, (uint32_t)ptn_size))
484 {
485 dprintf(CRITICAL, "ERROR: vbmeta read failure\n");
486 free(vbm_img_buf);
487 return;
488 }
489
490 *vbmeta_image_buf = vbm_img_buf;
491 *vbmeta_image_sz = (uint32_t)ptn_size;
492 return;
493}
494#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -0800495
lijuang102dfa92015-10-09 18:31:03 +0800496#if CHECK_BAT_VOLTAGE
497void update_battery_status(void)
498{
499 snprintf(battery_voltage,MAX_RSP_SIZE, "%d",target_get_battery_voltage());
500 snprintf(battery_soc_ok ,MAX_RSP_SIZE, "%s",target_battery_soc_ok()? "yes":"no");
501}
502#endif
503
michaellin6be1f392020-04-24 15:05:10 +0800504uint32_t GetPcbaVariant(void)
505{
506 uint8_t GPIO_97=10;
507 uint8_t GPIO_98=10;
508 uint8_t GPIO_99=10;
509
510 uint8_t pcba_stage = 0;
511
512 // Config GPIO
513 gpio_tlmm_config(97, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_ENABLE);
514 gpio_tlmm_config(98, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_ENABLE);
515 gpio_tlmm_config(99, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_ENABLE);
516
517 /* Wait for the gpio config to take effect - debounce time */
518 thread_sleep(10);
519
520 /* Get status of GPIO */
521 GPIO_97 = gpio_status(97);
522 GPIO_98 = gpio_status(98);
523 GPIO_99 = gpio_status(99);
524
525 pcba_stage = (GPIO_99 << 2) + (GPIO_98 << 1) + GPIO_97;
526 dprintf(ALWAYS, "pcba_stage status: %u\n", pcba_stage);
527 // GPIO_99 GPIO_98 GPIO_97
528 // 0 0 0 EP0
529 // 0 0 1 EP1
530 // 0 1 0 EP2
531 // 0 1 1 PP
michaellinaf8857a2020-05-05 14:58:47 +0800532 // 0 1 1 FP(8901MB-007)/PP
533 // 1 0 0 MP(8901MB-008)
534 // 1 0 1 MP-8903MB_001
michaellin6be1f392020-04-24 15:05:10 +0800535 return pcba_stage;
536}
537
Neeti Desaie245d492012-06-01 12:52:13 -0700538unsigned char *update_cmdline(const char * cmdline)
Brian Swetland9c4c0752009-01-25 16:23:50 -0800539{
David Ng183a7422009-12-07 14:55:21 -0800540 int cmdline_len = 0;
541 int have_cmdline = 0;
Amol Jadi168b7712012-03-06 16:15:00 -0800542 unsigned char *cmdline_final = NULL;
Neeti Desaie245d492012-06-01 12:52:13 -0700543 int pause_at_bootup = 0;
tracychui9d60fc52020-06-05 17:31:38 +0800544#if defined(ENABLE_PRODINFO_ACCESS)
545 int AdbEnable = 0;
546#endif
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800547 bool warm_boot = false;
Pavel Nedev5614d222013-06-17 18:01:02 +0300548 bool gpt_exists = partition_gpt_exists();
Joonwoo Park61112782013-10-02 19:50:39 -0700549 int have_target_boot_params = 0;
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700550 char *boot_dev_buf = NULL;
Monika Singh292b3e92018-03-17 22:40:23 +0530551#ifdef MDTP_SUPPORT
Mayank Grover351a75e2017-05-30 20:06:08 +0530552 bool is_mdtp_activated = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530553#endif
Mayank Grover351a75e2017-05-30 20:06:08 +0530554 int current_active_slot = INVALID;
Mayank Grover3804be72017-06-22 11:59:23 +0530555 int system_ptn_index = -1;
556 unsigned int lun = 0;
557 char lun_char_base = 'a';
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530558#if VERITY_LE
559 int syspath_buflen = strlen(verity_dev)
560 + strlen(verity_system_part) + (sizeof(char) * 2) + 2
561 + strlen(verity_params) + sizeof(int) + 2;
562#else
lijuang83ef4b22018-08-23 11:01:55 +0800563 int syspath_buflen = strlen(sys_path) + sizeof(int) + 2; /*allocate buflen for largest possible string*/
564 char dtbo_idx_str[MAX_DTBO_IDX_STR] = "\0";
565 int dtbo_idx = INVALID_PTN;
Parth Dixit1375d9e2019-07-08 20:56:13 +0530566 char dtb_idx_str[MAX_DTB_IDX_STR] = "\0";
567 int dtb_idx = INVALID_PTN;
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530568#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530569 char syspath_buf[syspath_buflen];
Mayank Grover466d6562018-05-10 14:52:20 +0530570#if HIBERNATION_SUPPORT
571 int resume_buflen = strlen(resume) + sizeof(int) + 2;
572 char resume_buf[resume_buflen];
573 int swap_ptn_index = INVALID_PTN;
574#endif
575
Mayank Grover889be1b2017-09-12 20:12:23 +0530576#if VERIFIED_BOOT
577 uint32_t boot_state = RED;
578#endif
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530579
580#if USE_LE_SYSTEMD
581 is_systemd_present=true;
582#endif
583
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700584#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530585 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +0530586 {
587 boot_state = boot_verify_get_state();
588 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530589#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700590
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200591#ifdef MDTP_SUPPORT
592 mdtp_activated(&is_mdtp_activated);
593#endif /* MDTP_SUPPORT */
Dima Zavin42168f22009-01-30 11:52:22 -0800594
Brian Swetland9c4c0752009-01-25 16:23:50 -0800595 if (cmdline && cmdline[0]) {
David Ng183a7422009-12-07 14:55:21 -0800596 cmdline_len = strlen(cmdline);
597 have_cmdline = 1;
598 }
599 if (target_is_emmc_boot()) {
600 cmdline_len += strlen(emmc_cmdline);
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700601 boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN);
Mayank Groverb716edf2019-05-08 16:06:55 +0530602 if (!boot_dev_buf) {
603 dprintf(CRITICAL, "ERROR: Failed to allocate boot_dev_buf\n");
604 } else {
lijuangd28587b2021-04-27 15:54:05 +0800605 platform_boot_dev_cmdline(boot_dev_buf, sizeof(char) * BOOT_DEV_MAX_LEN);
Mayank Groverb716edf2019-05-08 16:06:55 +0530606#if USE_BOOTDEV_CMDLINE
607 cmdline_len += strlen(boot_dev_buf);
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700608#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530609 if (target_dynamic_partition_supported()) {
610 cmdline_len += strlen(dynamic_bootdev_cmdline);
611 cmdline_len += strlen(boot_dev_buf);
612 }
613 }
David Ng183a7422009-12-07 14:55:21 -0800614 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800615
616 cmdline_len += strlen(usb_sn_cmdline);
617 cmdline_len += strlen(sn_buf);
tracychui9d60fc52020-06-05 17:31:38 +0800618#if defined(ENABLE_PRODINFO_ACCESS)
619 cmdline_len += strlen(cust_sn_cmdline);
620 cmdline_len += strlen(cust_sn_buf);
621 cmdline_len += strlen(factory_sn_cmdline);
622 cmdline_len += strlen(factory_sn_buf);
623#endif
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800624
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700625#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530626 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700627 {
Mayank Grover889be1b2017-09-12 20:12:23 +0530628 cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
629 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
630 {
631 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
632 ASSERT(0);
633 }
634 cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
635 cmdline_len += strlen(keymaster_v1);
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700636 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530637#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700638
Monika Singh292b3e92018-03-17 22:40:23 +0530639
640 if (vbcmdline != NULL) {
641 dprintf(DEBUG, "UpdateCmdLine vbcmdline present len %d\n",
642 strlen(vbcmdline));
643 cmdline_len += strlen(vbcmdline);
644 }
645
Pavel Nedev5614d222013-06-17 18:01:02 +0300646 if (boot_into_recovery && gpt_exists)
647 cmdline_len += strlen(secondary_gpt_enable);
648
Monika Singh292b3e92018-03-17 22:40:23 +0530649#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200650 if(is_mdtp_activated)
651 cmdline_len += strlen(mdtp_activated_flag);
Monika Singh292b3e92018-03-17 22:40:23 +0530652#endif
Pavel Nedev328ac822013-04-05 15:25:11 +0300653 if (boot_into_ffbm) {
654 cmdline_len += strlen(androidboot_mode);
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530655
656 if(is_systemd_present)
657 cmdline_len += strlen(systemd_ffbm_mode);
658
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700659 cmdline_len += strlen(ffbm_mode_string);
Pavel Nedev898298c2013-02-27 12:36:09 -0800660 /* reduce kernel console messages to speed-up boot */
661 cmdline_len += strlen(loglevel);
Matthew Qind886f3c2014-01-17 16:52:01 +0800662 } else if (boot_reason_alarm) {
663 cmdline_len += strlen(alarmboot_cmdline);
Zhenhua Huang431dafa2015-06-30 16:13:37 +0800664 } else if ((target_build_variant_user() || device.charger_screen_enabled)
lijuang266b17d2018-08-17 18:53:42 +0800665 && target_pause_for_battery_charge() && !boot_into_recovery) {
David Ngf773dde2010-07-26 19:55:08 -0700666 pause_at_bootup = 1;
667 cmdline_len += strlen(battchg_pause);
668 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800669
tracychui9d60fc52020-06-05 17:31:38 +0800670#if defined(ENABLE_PRODINFO_ACCESS)
671 if (prod.is_adb_enabled) {
672 dprintf(CRITICAL, "Device will enable adb\n");
673
674 prod.is_adb_enabled = 0;
675 write_prod_info(&prod);
676
677 AdbEnable = 1;
678 cmdline_len += strlen(UsbAdbEnable);
679 }
680#endif
681
Shashank Mittalcd98d472011-08-02 14:29:24 -0700682 if(target_use_signed_kernel() && auth_kernel_img) {
683 cmdline_len += strlen(auth_kernel);
684 }
685
Joonwoo Park61112782013-10-02 19:50:39 -0700686 if (get_target_boot_params(cmdline, boot_into_recovery ? "recoveryfs" :
687 "system",
vijay kumar870515d2015-08-31 16:37:24 +0530688 &target_boot_params) == 0) {
Joonwoo Park61112782013-10-02 19:50:39 -0700689 have_target_boot_params = 1;
690 cmdline_len += strlen(target_boot_params);
691 }
692
Ajay Dudanid04110c2011-01-17 23:55:07 -0800693 /* Determine correct androidboot.baseband to use */
694 switch(target_baseband())
695 {
696 case BASEBAND_APQ:
697 cmdline_len += strlen(baseband_apq);
698 break;
699
700 case BASEBAND_MSM:
701 cmdline_len += strlen(baseband_msm);
702 break;
703
704 case BASEBAND_CSFB:
705 cmdline_len += strlen(baseband_csfb);
706 break;
707
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800708 case BASEBAND_SVLTE2A:
709 cmdline_len += strlen(baseband_svlte2a);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800710 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700711
712 case BASEBAND_MDM:
713 cmdline_len += strlen(baseband_mdm);
714 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700715
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800716 case BASEBAND_MDM2:
717 cmdline_len += strlen(baseband_mdm2);
718 break;
719
Amol Jadi5c61a952012-05-04 17:05:35 -0700720 case BASEBAND_SGLTE:
721 cmdline_len += strlen(baseband_sglte);
722 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530723
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800724 case BASEBAND_SGLTE2:
725 cmdline_len += strlen(baseband_sglte2);
726 break;
727
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530728 case BASEBAND_DSDA:
729 cmdline_len += strlen(baseband_dsda);
730 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800731
732 case BASEBAND_DSDA2:
733 cmdline_len += strlen(baseband_dsda2);
734 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530735 case BASEBAND_APQ_NOWGR:
736 cmdline_len += strlen(baseband_apq_nowgr);
737 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800738 }
739
michaellin6be1f392020-04-24 15:05:10 +0800740 switch(GetPcbaVariant())
741 {
742 case 0: // EP0
743 cmdline_len += strlen(PCBA_STAGE_0);
744 break;
745
746 case 1: // EP1
747 cmdline_len += strlen(PCBA_STAGE_1);
748 break;
749
750 case 2: // EP2
751 cmdline_len += strlen(PCBA_STAGE_2);
752 break;
753
michaellinaf8857a2020-05-05 14:58:47 +0800754 case 3: // FP(8901MB-007)/PP
michaellin6be1f392020-04-24 15:05:10 +0800755 cmdline_len += strlen(PCBA_STAGE_3);
756 break;
757
michaellinaf8857a2020-05-05 14:58:47 +0800758 case 4: // MP(8901MB-008)
michaellin6be1f392020-04-24 15:05:10 +0800759 cmdline_len += strlen(PCBA_STAGE_4);
760 break;
761
michaellinaf8857a2020-05-05 14:58:47 +0800762 case 5: // MP-8903MB_001
763 cmdline_len += strlen(PCBA_STAGE_5);
764 break;
765
michaellin6be1f392020-04-24 15:05:10 +0800766 default:// Reserved
767 cmdline_len += strlen(PCBA_STAGE_F);
768 break;
769 }
770
tracychui792d2ad2020-06-15 10:50:49 +0800771 if(smem_get_ddr_size() == MEM_3GB )
772 {
773 cmdline_len += strlen(memory_config_3G);
774 }
775 else
776 {
777 cmdline_len += strlen(memory_config_4G);
778 }
779
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300780#if ENABLE_DISPLAY
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800781 if (cmdline) {
782 if ((strstr(cmdline, DISPLAY_DEFAULT_PREFIX) == NULL) &&
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530783 target_display_panel_node(display_panel_buf,
784 MAX_PANEL_BUF_SIZE) &&
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800785 strlen(display_panel_buf)) {
786 cmdline_len += strlen(display_panel_buf);
787 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700788 }
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300789#endif
Dhaval Patel223ec952013-07-18 14:49:44 -0700790
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800791 if (target_warm_boot()) {
792 warm_boot = true;
793 cmdline_len += strlen(warmboot_cmdline);
794 }
795
Mayank Grover5384ed82018-05-09 12:09:24 +0530796 if (target_uses_system_as_root() ||
797 partition_multislot_is_supported())
Mayank Grover351a75e2017-05-30 20:06:08 +0530798 {
799 current_active_slot = partition_find_active_slot();
800 cmdline_len += (strlen(androidboot_slot_suffix)+
801 strlen(SUFFIX_SLOT(current_active_slot)));
802
Mayank Grover3804be72017-06-22 11:59:23 +0530803 system_ptn_index = partition_get_index("system");
804 if (platform_boot_dev_isemmc())
805 {
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530806#if VERITY_LE
807 /*
808 Condition 4: Verity and A/B both enabled
809 Eventual command line looks like:
810 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
811 ... root=/dev/dm-0 dm="system_<slot_suffix> none ro,0 1 android-verity /dev/mmcblk0p<NN>"
812 */
813 snprintf(syspath_buf, syspath_buflen, " %s %s%s %s%d\"",
814 verity_dev,
815 verity_system_part, suffix_slot[current_active_slot],
816 verity_params, system_ptn_index + 1);
817#else
818 /*
819 Condition 5: A/B enabled, but verity disabled
820 Eventual command line looks like:
821 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
822 ... root=/dev/mmcblk0p<NN> ...
823 */
824 snprintf(syspath_buf, syspath_buflen, " %s%d",
825 sys_path, system_ptn_index + 1);
826#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530827 }
828 else
829 {
830 lun = partition_get_lun(system_ptn_index);
831 snprintf(syspath_buf, syspath_buflen, " root=/dev/sd%c%d",
832 lun_char_base + lun,
833 partition_get_index_in_lun("system", lun));
834 }
Mayank Grover351a75e2017-05-30 20:06:08 +0530835
Monika Singh292b3e92018-03-17 22:40:23 +0530836#ifndef VERIFIED_BOOT_2
Mayank Grover3804be72017-06-22 11:59:23 +0530837 cmdline_len += strlen(syspath_buf);
Monika Singh292b3e92018-03-17 22:40:23 +0530838#endif
Mayank Grover5384ed82018-05-09 12:09:24 +0530839 }
840
841 if (target_uses_system_as_root() ||
842 partition_multislot_is_supported())
843 {
844 cmdline_len += strlen(sys_path_cmdline);
Mayank Groverb716edf2019-05-08 16:06:55 +0530845
846 /* For dynamic partition, support skip skip_initramfs */
847 if (!target_dynamic_partition_supported() &&
848 !boot_into_recovery)
Mayank Grover351a75e2017-05-30 20:06:08 +0530849 cmdline_len += strlen(skip_ramfs);
850 }
851
Mayank Grover466d6562018-05-10 14:52:20 +0530852#if HIBERNATION_SUPPORT
853 if (platform_boot_dev_isemmc())
854 {
855 swap_ptn_index = partition_get_index("swap");
856 if (swap_ptn_index != INVALID_PTN)
857 {
858 snprintf(resume_buf, resume_buflen,
859 " %s%d", resume,
860 (swap_ptn_index + 1));
861 cmdline_len += strlen(resume_buf);
862 }
863 else
864 {
865 dprintf(INFO, "WARNING: swap partition not found\n");
866 }
867 }
868#endif
869
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800870#if TARGET_CMDLINE_SUPPORT
871 char *target_cmdline_buf = malloc(TARGET_MAX_CMDLNBUF);
872 int target_cmd_line_len;
873 ASSERT(target_cmdline_buf);
874 target_cmd_line_len = target_update_cmdline(target_cmdline_buf);
875 cmdline_len += target_cmd_line_len;
876#endif
877
lijuang83ef4b22018-08-23 11:01:55 +0800878#if !VERITY_LE
879 dtbo_idx = get_dtbo_idx ();
880 if (dtbo_idx != INVALID_PTN) {
881 snprintf(dtbo_idx_str, sizeof(dtbo_idx_str), "%s%d",
882 android_boot_dtbo_idx, dtbo_idx);
883 cmdline_len += strlen (dtbo_idx_str);
884 }
Parth Dixit1375d9e2019-07-08 20:56:13 +0530885
886 dtb_idx = get_dtb_idx ();
887 if (dtb_idx != INVALID_PTN) {
888 snprintf(dtb_idx_str, sizeof(dtb_idx_str), "%s%d",
889 android_boot_dtb_idx, dtb_idx);
890 cmdline_len += strlen (dtb_idx_str);
891 }
lijuang83ef4b22018-08-23 11:01:55 +0800892#endif
893
jhchena8a15dd2020-04-24 15:45:57 +0800894#ifdef ENABLE_FUSE_CHECK
895 {
896 int hw_key_status = readl(0xA01D0);
897 is_fused = (hw_key_status & 0x2) >> 1;
898 dprintf(CRITICAL, "hw_key_status = 0x%x, is_fused=%d\n", hw_key_status, is_fused);
899 if (is_fused) {
900 cmdline_len += strlen(fuse_blown);
901 } else {
902 cmdline_len += strlen(fuse_not_blown);
903 }
904 }
905#endif
906
David Ng183a7422009-12-07 14:55:21 -0800907 if (cmdline_len > 0) {
908 const char *src;
Maria Yu52254c02014-07-04 16:14:54 +0800909 unsigned char *dst;
910
911 cmdline_final = (unsigned char*) malloc((cmdline_len + 4) & (~3));
912 ASSERT(cmdline_final != NULL);
vijay kumar287bb542015-09-29 13:01:52 +0530913 memset((void *)cmdline_final, 0, sizeof(*cmdline_final));
Maria Yu52254c02014-07-04 16:14:54 +0800914 dst = cmdline_final;
Neeti Desaie245d492012-06-01 12:52:13 -0700915
Amol Jadi168b7712012-03-06 16:15:00 -0800916 /* Save start ptr for debug print */
David Ng183a7422009-12-07 14:55:21 -0800917 if (have_cmdline) {
918 src = cmdline;
919 while ((*dst++ = *src++));
920 }
921 if (target_is_emmc_boot()) {
922 src = emmc_cmdline;
923 if (have_cmdline) --dst;
David Ngf773dde2010-07-26 19:55:08 -0700924 have_cmdline = 1;
925 while ((*dst++ = *src++));
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800926#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700927 src = boot_dev_buf;
Mayank Groverb716edf2019-05-08 16:06:55 +0530928 if (have_cmdline &&
929 boot_dev_buf) {
930 --dst;
931 while ((*dst++ = *src++));
932 }
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700933#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530934 /* Dynamic partition append boot_devices */
935 if (target_dynamic_partition_supported() &&
936 boot_dev_buf) {
937 src = dynamic_bootdev_cmdline;
938 if (have_cmdline) --dst;
939 while ((*dst++ = *src++));
940 src = boot_dev_buf;
941 if (have_cmdline) --dst;
942 while ((*dst++ = *src++));
943 }
David Ngf773dde2010-07-26 19:55:08 -0700944 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800945
michaellin6be1f392020-04-24 15:05:10 +0800946 switch(GetPcbaVariant())
947 {
948 case 0:
949 src = PCBA_STAGE_0;
950 if (have_cmdline) --dst;
951 while ((*dst++ = *src++));
952 break;
953 case 1:
954 src = PCBA_STAGE_1;
955 if (have_cmdline) --dst;
956 while ((*dst++ = *src++));
957 break;
958 case 2:
959 src = PCBA_STAGE_2;
960 if (have_cmdline) --dst;
961 while ((*dst++ = *src++));
962 break;
963 case 3:
964 src = PCBA_STAGE_3;
965 if (have_cmdline) --dst;
966 while ((*dst++ = *src++));
967 break;
968 case 4:
969 src = PCBA_STAGE_4;
970 if (have_cmdline) --dst;
971 while ((*dst++ = *src++));
972 break;
michaellinaf8857a2020-05-05 14:58:47 +0800973 case 5:
974 src = PCBA_STAGE_5;
975 if (have_cmdline) --dst;
976 while ((*dst++ = *src++));
977 break;
michaellin6be1f392020-04-24 15:05:10 +0800978 default:
979 src = PCBA_STAGE_F;
980 if (have_cmdline) --dst;
981 while ((*dst++ = *src++));
982 break;
983 }
tracychui792d2ad2020-06-15 10:50:49 +0800984 if(smem_get_ddr_size() == MEM_3GB )
985 {
986 src = memory_config_3G;
987 if (have_cmdline) --dst;
988 while ((*dst++ = *src++));
989 }
990 else
991 {
992 src = memory_config_4G;
993 if (have_cmdline) --dst;
994 while ((*dst++ = *src++));
995 }
michaellin6be1f392020-04-24 15:05:10 +0800996
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700997#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530998 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700999 {
Mayank Grover889be1b2017-09-12 20:12:23 +05301000 src = verified_state;
1001 if(have_cmdline) --dst;
1002 have_cmdline = 1;
1003 while ((*dst++ = *src++));
1004 src = vbsn[boot_state].name;
1005 if(have_cmdline) --dst;
1006 while ((*dst++ = *src++));
1007
1008 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
1009 {
1010 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
1011 ASSERT(0);
1012 }
1013 src = verity_mode;
1014 if(have_cmdline) --dst;
1015 while ((*dst++ = *src++));
1016 src = vbvm[device.verity_mode].name;
1017 if(have_cmdline) -- dst;
1018 while ((*dst++ = *src++));
1019 src = keymaster_v1;
1020 if(have_cmdline) --dst;
1021 while ((*dst++ = *src++));
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -07001022 }
Parth Dixitddbc7352015-10-18 03:13:31 +05301023#endif
Monika Singh292b3e92018-03-17 22:40:23 +05301024
1025 if (vbcmdline != NULL) {
1026 src = vbcmdline;
1027 if (have_cmdline) --dst;
1028 while ((*dst++ = *src++));
1029 }
1030
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08001031 src = usb_sn_cmdline;
1032 if (have_cmdline) --dst;
1033 have_cmdline = 1;
1034 while ((*dst++ = *src++));
1035 src = sn_buf;
1036 if (have_cmdline) --dst;
1037 have_cmdline = 1;
1038 while ((*dst++ = *src++));
tracychui9d60fc52020-06-05 17:31:38 +08001039
1040 #if defined(ENABLE_PRODINFO_ACCESS)
1041 src = cust_sn_cmdline;
1042 if (have_cmdline) --dst;
1043 have_cmdline = 1;
1044 while ((*dst++ = *src++));
1045 src = cust_sn_buf;
1046 if (have_cmdline) --dst;
1047 have_cmdline = 1;
1048 while ((*dst++ = *src++));
1049 src = factory_sn_cmdline;
1050 if (have_cmdline) --dst;
1051 have_cmdline = 1;
1052 while ((*dst++ = *src++));
1053 src = factory_sn_buf;
1054 if (have_cmdline) --dst;
1055 have_cmdline = 1;
1056 while ((*dst++ = *src++));
1057 #endif
Hanumant Singh8e1ac232014-01-29 13:41:51 -08001058 if (warm_boot) {
1059 if (have_cmdline) --dst;
1060 src = warmboot_cmdline;
1061 while ((*dst++ = *src++));
1062 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08001063
Pavel Nedev5614d222013-06-17 18:01:02 +03001064 if (boot_into_recovery && gpt_exists) {
1065 src = secondary_gpt_enable;
1066 if (have_cmdline) --dst;
1067 while ((*dst++ = *src++));
1068 }
Monika Singh292b3e92018-03-17 22:40:23 +05301069#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +02001070 if (is_mdtp_activated) {
1071 src = mdtp_activated_flag;
1072 if (have_cmdline) --dst;
1073 while ((*dst++ = *src++));
1074 }
Monika Singh292b3e92018-03-17 22:40:23 +05301075#endif
Pavel Nedev328ac822013-04-05 15:25:11 +03001076 if (boot_into_ffbm) {
1077 src = androidboot_mode;
1078 if (have_cmdline) --dst;
1079 while ((*dst++ = *src++));
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001080 src = ffbm_mode_string;
Pavel Nedev328ac822013-04-05 15:25:11 +03001081 if (have_cmdline) --dst;
1082 while ((*dst++ = *src++));
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +05301083
1084 if(is_systemd_present) {
1085 src = systemd_ffbm_mode;
1086 if (have_cmdline) --dst;
1087 while ((*dst++ = *src++));
1088 }
1089
Pavel Nedev898298c2013-02-27 12:36:09 -08001090 src = loglevel;
1091 if (have_cmdline) --dst;
1092 while ((*dst++ = *src++));
Matthew Qind886f3c2014-01-17 16:52:01 +08001093 } else if (boot_reason_alarm) {
1094 src = alarmboot_cmdline;
1095 if (have_cmdline) --dst;
1096 while ((*dst++ = *src++));
Pavel Nedev328ac822013-04-05 15:25:11 +03001097 } else if (pause_at_bootup) {
David Ngf773dde2010-07-26 19:55:08 -07001098 src = battchg_pause;
1099 if (have_cmdline) --dst;
David Ng183a7422009-12-07 14:55:21 -08001100 while ((*dst++ = *src++));
1101 }
Ajay Dudanid04110c2011-01-17 23:55:07 -08001102
tracychui9d60fc52020-06-05 17:31:38 +08001103#if defined(ENABLE_PRODINFO_ACCESS)
1104 if (AdbEnable) {
1105 src = UsbAdbEnable;
1106 if (have_cmdline) --dst;
1107 while ((*dst++ = *src++));
1108 }
1109#endif
1110
Shashank Mittalcd98d472011-08-02 14:29:24 -07001111 if(target_use_signed_kernel() && auth_kernel_img) {
1112 src = auth_kernel;
1113 if (have_cmdline) --dst;
1114 while ((*dst++ = *src++));
1115 }
1116
Ajay Dudanid04110c2011-01-17 23:55:07 -08001117 switch(target_baseband())
1118 {
1119 case BASEBAND_APQ:
1120 src = baseband_apq;
1121 if (have_cmdline) --dst;
1122 while ((*dst++ = *src++));
1123 break;
1124
1125 case BASEBAND_MSM:
1126 src = baseband_msm;
1127 if (have_cmdline) --dst;
1128 while ((*dst++ = *src++));
1129 break;
1130
1131 case BASEBAND_CSFB:
1132 src = baseband_csfb;
1133 if (have_cmdline) --dst;
1134 while ((*dst++ = *src++));
1135 break;
1136
Ajay Dudani6cff85e2011-02-04 16:02:16 -08001137 case BASEBAND_SVLTE2A:
1138 src = baseband_svlte2a;
Ajay Dudanid04110c2011-01-17 23:55:07 -08001139 if (have_cmdline) --dst;
1140 while ((*dst++ = *src++));
1141 break;
Ajay Dudani403bc492011-09-30 16:17:21 -07001142
1143 case BASEBAND_MDM:
1144 src = baseband_mdm;
1145 if (have_cmdline) --dst;
1146 while ((*dst++ = *src++));
1147 break;
Amol Jadi5c61a952012-05-04 17:05:35 -07001148
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -08001149 case BASEBAND_MDM2:
1150 src = baseband_mdm2;
1151 if (have_cmdline) --dst;
1152 while ((*dst++ = *src++));
1153 break;
1154
Amol Jadi5c61a952012-05-04 17:05:35 -07001155 case BASEBAND_SGLTE:
1156 src = baseband_sglte;
1157 if (have_cmdline) --dst;
1158 while ((*dst++ = *src++));
1159 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +05301160
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -08001161 case BASEBAND_SGLTE2:
1162 src = baseband_sglte2;
1163 if (have_cmdline) --dst;
1164 while ((*dst++ = *src++));
1165 break;
1166
Channagoud Kadabi141f2982012-10-31 11:23:02 +05301167 case BASEBAND_DSDA:
1168 src = baseband_dsda;
1169 if (have_cmdline) --dst;
1170 while ((*dst++ = *src++));
1171 break;
Amol Jadi2a15a272013-01-22 12:03:36 -08001172
1173 case BASEBAND_DSDA2:
1174 src = baseband_dsda2;
1175 if (have_cmdline) --dst;
1176 while ((*dst++ = *src++));
1177 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +05301178 case BASEBAND_APQ_NOWGR:
1179 src = baseband_apq_nowgr;
1180 if (have_cmdline) --dst;
1181 while ((*dst++ = *src++));
1182 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -08001183 }
Dhaval Patel223ec952013-07-18 14:49:44 -07001184
1185 if (strlen(display_panel_buf)) {
Dhaval Patel223ec952013-07-18 14:49:44 -07001186 src = display_panel_buf;
1187 if (have_cmdline) --dst;
1188 while ((*dst++ = *src++));
1189 }
Joonwoo Park61112782013-10-02 19:50:39 -07001190
1191 if (have_target_boot_params) {
1192 if (have_cmdline) --dst;
1193 src = target_boot_params;
1194 while ((*dst++ = *src++));
vijay kumar870515d2015-08-31 16:37:24 +05301195 free(target_boot_params);
Joonwoo Park61112782013-10-02 19:50:39 -07001196 }
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -08001197
Mayank Grover351a75e2017-05-30 20:06:08 +05301198 if (partition_multislot_is_supported() && have_cmdline)
1199 {
1200 src = androidboot_slot_suffix;
1201 --dst;
1202 while ((*dst++ = *src++));
1203 --dst;
1204 src = SUFFIX_SLOT(current_active_slot);
1205 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +05301206 }
Mayank Grover351a75e2017-05-30 20:06:08 +05301207
Mayank Grover351a75e2017-05-30 20:06:08 +05301208
Mayank Grover5384ed82018-05-09 12:09:24 +05301209 /*
1210 * System-As-Root behaviour, system.img should contain both
1211 * system content and ramdisk content, and should be mounted at
1212 * root(a/b).
1213 * Apending skip_ramfs for non a/b builds which use, system as root.
1214 */
1215 if ((target_uses_system_as_root() ||
1216 partition_multislot_is_supported()) &&
1217 have_cmdline)
1218 {
Mayank Groverb716edf2019-05-08 16:06:55 +05301219 if (!target_dynamic_partition_supported() &&
1220 !boot_into_recovery)
Mayank Grover5384ed82018-05-09 12:09:24 +05301221 {
1222 src = skip_ramfs;
Mayank Grover351a75e2017-05-30 20:06:08 +05301223 --dst;
1224 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +05301225 }
1226
1227 src = sys_path_cmdline;
1228 --dst;
1229 while ((*dst++ = *src++));
Mayank Grover3804be72017-06-22 11:59:23 +05301230
Monika Singh292b3e92018-03-17 22:40:23 +05301231#ifndef VERIFIED_BOOT_2
Mayank Grover5384ed82018-05-09 12:09:24 +05301232 src = syspath_buf;
1233 --dst;
1234 while ((*dst++ = *src++));
Monika Singh292b3e92018-03-17 22:40:23 +05301235#endif
Mayank Grover351a75e2017-05-30 20:06:08 +05301236 }
1237
Mayank Grover466d6562018-05-10 14:52:20 +05301238#if HIBERNATION_SUPPORT
1239 if (swap_ptn_index != INVALID_PTN)
1240 {
1241 src = resume_buf;
1242 --dst;
1243 while ((*dst++ = *src++));
1244 }
1245#endif
1246
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -08001247#if TARGET_CMDLINE_SUPPORT
1248 if (target_cmdline_buf && target_cmd_line_len)
1249 {
1250 if (have_cmdline) --dst;
1251 src = target_cmdline_buf;
1252 while((*dst++ = *src++));
1253 free(target_cmdline_buf);
1254 }
1255#endif
lijuang83ef4b22018-08-23 11:01:55 +08001256
1257#if !VERITY_LE
1258 if (dtbo_idx != INVALID_PTN) {
1259 src = dtbo_idx_str;
1260 --dst;
1261 while ((*dst++ = *src++));
1262 }
Parth Dixit1375d9e2019-07-08 20:56:13 +05301263
1264 if (dtb_idx != INVALID_PTN) {
1265 src = dtb_idx_str;
1266 --dst;
1267 while ((*dst++ = *src++));
1268 }
lijuang83ef4b22018-08-23 11:01:55 +08001269#endif
jhchena8a15dd2020-04-24 15:45:57 +08001270
1271#ifdef ENABLE_FUSE_CHECK
1272 if (is_fused) {
1273 src = fuse_blown;
1274 if (have_cmdline) --dst;
1275 while ((*dst++ = *src++));
1276 } else {
1277 src = fuse_not_blown;
1278 if (have_cmdline) --dst;
1279 while ((*dst++ = *src++));
1280 }
1281#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001282 }
Dhaval Patel223ec952013-07-18 14:49:44 -07001283
1284
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -07001285 if (boot_dev_buf)
1286 free(boot_dev_buf);
1287
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08001288 if (cmdline_final)
1289 dprintf(INFO, "cmdline: %s\n", cmdline_final);
1290 else
1291 dprintf(INFO, "cmdline is NULL\n");
Neeti Desaie245d492012-06-01 12:52:13 -07001292 return cmdline_final;
1293}
1294
1295unsigned *atag_core(unsigned *ptr)
1296{
1297 /* CORE */
1298 *ptr++ = 2;
1299 *ptr++ = 0x54410001;
1300
1301 return ptr;
1302
1303}
1304
1305unsigned *atag_ramdisk(unsigned *ptr, void *ramdisk,
1306 unsigned ramdisk_size)
1307{
1308 if (ramdisk_size) {
1309 *ptr++ = 4;
1310 *ptr++ = 0x54420005;
1311 *ptr++ = (unsigned)ramdisk;
1312 *ptr++ = ramdisk_size;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001313 }
1314
Neeti Desaie245d492012-06-01 12:52:13 -07001315 return ptr;
1316}
1317
1318unsigned *atag_ptable(unsigned **ptr_addr)
1319{
1320 int i;
1321 struct ptable *ptable;
1322
1323 if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001324 *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
1325 sizeof(unsigned)));
Neeti Desaie245d492012-06-01 12:52:13 -07001326 *(*ptr_addr)++ = 0x4d534d70;
1327 for (i = 0; i < ptable->count; ++i)
1328 ptentry_to_tag(ptr_addr, ptable_get(ptable, i));
1329 }
1330
1331 return (*ptr_addr);
1332}
1333
1334unsigned *atag_cmdline(unsigned *ptr, const char *cmdline)
1335{
1336 int cmdline_length = 0;
1337 int n;
Neeti Desaie245d492012-06-01 12:52:13 -07001338 char *dest;
1339
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001340 cmdline_length = strlen((const char*)cmdline);
Neeti Desaie245d492012-06-01 12:52:13 -07001341 n = (cmdline_length + 4) & (~3);
1342
1343 *ptr++ = (n / 4) + 2;
1344 *ptr++ = 0x54410009;
1345 dest = (char *) ptr;
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001346 while ((*dest++ = *cmdline++));
Neeti Desaie245d492012-06-01 12:52:13 -07001347 ptr += (n / 4);
1348
1349 return ptr;
1350}
1351
1352unsigned *atag_end(unsigned *ptr)
1353{
Brian Swetland9c4c0752009-01-25 16:23:50 -08001354 /* END */
1355 *ptr++ = 0;
1356 *ptr++ = 0;
1357
Neeti Desaie245d492012-06-01 12:52:13 -07001358 return ptr;
1359}
1360
1361void generate_atags(unsigned *ptr, const char *cmdline,
1362 void *ramdisk, unsigned ramdisk_size)
1363{
vijay kumar21a37452015-12-29 16:23:21 +05301364 unsigned *orig_ptr = ptr;
Neeti Desaie245d492012-06-01 12:52:13 -07001365 ptr = atag_core(ptr);
1366 ptr = atag_ramdisk(ptr, ramdisk, ramdisk_size);
1367 ptr = target_atag_mem(ptr);
1368
1369 /* Skip NAND partition ATAGS for eMMC boot */
1370 if (!target_is_emmc_boot()){
1371 ptr = atag_ptable(&ptr);
1372 }
1373
vijay kumar21a37452015-12-29 16:23:21 +05301374 /*
1375 * Atags size filled till + cmdline size + 1 unsigned for 4-byte boundary + 4 unsigned
1376 * for atag identifier in atag_cmdline and atag_end should be with in MAX_TAGS_SIZE bytes
1377 */
Mayank Groverbc8a2ef2018-02-23 18:03:36 +05301378 if (!cmdline)
1379 return;
1380
vijay kumar21a37452015-12-29 16:23:21 +05301381 if (((ptr - orig_ptr) + strlen(cmdline) + 5 * sizeof(unsigned)) < MAX_TAGS_SIZE) {
1382 ptr = atag_cmdline(ptr, cmdline);
1383 ptr = atag_end(ptr);
1384 }
1385 else {
1386 dprintf(CRITICAL,"Crossing ATAGs Max size allowed\n");
1387 ASSERT(0);
1388 }
Neeti Desaie245d492012-06-01 12:52:13 -07001389}
1390
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001391typedef void entry_func_ptr(unsigned, unsigned, unsigned*);
Neeti Desaie245d492012-06-01 12:52:13 -07001392void boot_linux(void *kernel, unsigned *tags,
1393 const char *cmdline, unsigned machtype,
1394 void *ramdisk, unsigned ramdisk_size)
1395{
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001396 unsigned char *final_cmdline;
Amol Jadib6be5c12012-11-14 13:39:51 -08001397#if DEVICE_TREE
Neeti Desai17379b82012-06-04 18:42:53 -07001398 int ret = 0;
Amol Jadib6be5c12012-11-14 13:39:51 -08001399#endif
1400
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001401 void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001402 uint32_t tags_phys = PA((addr_t)tags);
vijay kumar1a50a642015-11-16 12:41:15 +05301403 struct kernel64_hdr *kptr = ((struct kernel64_hdr*)(PA((addr_t)kernel)));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001404
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301405 ramdisk = (void *)PA((addr_t)ramdisk);
Neeti Desaie245d492012-06-01 12:52:13 -07001406
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001407 final_cmdline = update_cmdline((const char*)cmdline);
1408
Neeti Desai17379b82012-06-04 18:42:53 -07001409#if DEVICE_TREE
Amol Jadib6be5c12012-11-14 13:39:51 -08001410 dprintf(INFO, "Updating device tree: start\n");
1411
Neeti Desai17379b82012-06-04 18:42:53 -07001412 /* Update the Device Tree */
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301413 ret = update_device_tree((void *)tags,(const char *)final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001414 if(ret)
1415 {
1416 dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
1417 ASSERT(0);
1418 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001419 dprintf(INFO, "Updating device tree: done\n");
Neeti Desai17379b82012-06-04 18:42:53 -07001420#else
Neeti Desaie245d492012-06-01 12:52:13 -07001421 /* Generating the Atags */
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001422 generate_atags(tags, final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001423#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001424
Monika Singh0ec6db82019-07-18 16:57:58 +05301425#if VERIFIED_BOOT
Monika Singhb0db4b82018-09-26 12:18:02 +05301426 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05301427 {
1428 if (device.verity_mode == 0) {
lijuangbdd9bb42016-03-01 18:22:17 +08001429#if FBCON_DISPLAY_MSG
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001430#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05301431 display_bootverify_menu(DISPLAY_MENU_EIO);
1432 wait_for_users_action();
1433 if(!pwr_key_is_pressed)
1434 shutdown_device();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001435#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301436 display_bootverify_menu(DISPLAY_MENU_LOGGING);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001437#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301438 wait_for_users_action();
lijuangbdd9bb42016-03-01 18:22:17 +08001439#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301440 dprintf(CRITICAL,
1441 "The dm-verity is not started in enforcing mode.\nWait for 5 seconds before proceeding\n");
1442 mdelay(5000);
lijuangbdd9bb42016-03-01 18:22:17 +08001443#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301444 }
lijuangbdd9bb42016-03-01 18:22:17 +08001445 }
lijuangbdd9bb42016-03-01 18:22:17 +08001446#endif
1447
1448#if VERIFIED_BOOT
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001449 /* Write protect the device info */
Channagoud Kadabi3bd9d1e2015-05-05 16:18:20 -07001450 if (!boot_into_recovery && target_build_variant_user() && devinfo_present && mmc_write_protect("devinfo", 1))
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001451 {
1452 dprintf(INFO, "Failed to write protect dev info\n");
1453 ASSERT(0);
1454 }
1455#endif
1456
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001457 /* Turn off splash screen if enabled */
1458#if DISPLAY_SPLASH_SCREEN
1459 target_display_shutdown();
1460#endif
1461
Veera Sundaram Sankaran67ea0932015-09-25 10:09:30 -07001462 /* Perform target specific cleanup */
1463 target_uninit();
Monika Singh292b3e92018-03-17 22:40:23 +05301464 free_verified_boot_resource(&info);
1465 if (final_cmdline)
1466 free(final_cmdline);
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001467
Deepa Dinamani33734bc2013-03-06 12:16:06 -08001468 dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d), tags/device tree @ %p\n",
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301469 entry, ramdisk, ramdisk_size, (void *)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001470
1471 enter_critical_section();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001472
Amol Jadi4421e652011-06-16 15:00:48 -07001473 /* do any platform specific cleanup before kernel entry */
1474 platform_uninit();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001475
Brian Swetland9c4c0752009-01-25 16:23:50 -08001476 arch_disable_cache(UCACHE);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001477
Amol Jadi504f9fe2012-08-16 13:56:48 -07001478#if ARM_WITH_MMU
Brian Swetland9c4c0752009-01-25 16:23:50 -08001479 arch_disable_mmu();
Amol Jadi504f9fe2012-08-16 13:56:48 -07001480#endif
Amol Jadi492d5a52013-03-15 16:12:34 -07001481 bs_set_timestamp(BS_KERNEL_ENTRY);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001482
1483 if (IS_ARM64(kptr))
1484 /* Jump to a 64bit kernel */
1485 scm_elexec_call((paddr_t)kernel, tags_phys);
1486 else
1487 /* Jump to a 32bit kernel */
1488 entry(0, machtype, (unsigned*)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001489}
1490
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001491/* Function to check if the memory address range falls within the aboot
1492 * boundaries.
1493 * start: Start of the memory region
1494 * size: Size of the memory region
1495 */
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301496int check_aboot_addr_range_overlap(uintptr_t start, uint32_t size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001497{
1498 /* Check for boundary conditions. */
Sundarajan Srinivasance2a0ea2013-12-16 17:02:56 -08001499 if ((UINT_MAX - start) < size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001500 return -1;
1501
1502 /* Check for memory overlap. */
1503 if ((start < MEMBASE) && ((start + size) <= MEMBASE))
1504 return 0;
Channagoud Kadabi94143912013-10-15 12:53:52 -07001505 else if (start >= (MEMBASE + MEMSIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001506 return 0;
1507 else
1508 return -1;
1509}
1510
Mayank Grovere559cec2017-10-17 15:12:03 +05301511/* Function to check if the memory address range falls beyond ddr region.
1512 * start: Start of the memory region
1513 * size: Size of the memory region
1514 */
1515int check_ddr_addr_range_bound(uintptr_t start, uint32_t size)
1516{
1517 uintptr_t ddr_pa_start_addr = PA(get_ddr_start());
1518 uint64_t ddr_size = smem_get_ddr_size();
1519 uint64_t ddr_pa_end_addr = ddr_pa_start_addr + ddr_size;
1520 uintptr_t pa_start_addr = PA(start);
1521
1522 /* Check for boundary conditions. */
1523 if ((UINT_MAX - start) < size)
1524 return -1;
1525
1526 /* Check if memory range is beyond the ddr range. */
1527 if (pa_start_addr < ddr_pa_start_addr ||
1528 pa_start_addr >= (ddr_pa_end_addr) ||
1529 (pa_start_addr + size) > ddr_pa_end_addr)
1530 return -1;
1531 else
1532 return 0;
1533}
1534
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001535BUF_DMA_ALIGN(buf, BOOT_IMG_MAX_PAGE_SIZE); //Equal to max-supported pagesize
Dima Zavin214cc642009-01-26 11:16:21 -08001536
Mayank Groverdd080e82018-09-04 20:12:13 +05301537int getimage(void **image_buffer, uint32_t *imgsize,
1538 const char *imgname)
Monika Singh292b3e92018-03-17 22:40:23 +05301539{
Mayank Groverdd080e82018-09-04 20:12:13 +05301540 uint32_t loadedindex;
1541 if (image_buffer == NULL || imgsize == NULL ||
Monika Singh292b3e92018-03-17 22:40:23 +05301542 imgname == NULL) {
1543 dprintf(CRITICAL, "getimage: invalid parameters\n");
1544 return -1;
1545 }
Mayank Groverdd080e82018-09-04 20:12:13 +05301546 for (loadedindex = 0; loadedindex < info.num_loaded_images; loadedindex++) {
1547 if (!strncmp(info.images[loadedindex].name, imgname,
Monika Singh292b3e92018-03-17 22:40:23 +05301548 strlen(imgname))) {
Mayank Groverdd080e82018-09-04 20:12:13 +05301549 *image_buffer = info.images[loadedindex].image_buffer;
1550 *imgsize = info.images[loadedindex].imgsize;
Mayank Grover027a9412018-09-04 15:12:05 +05301551 dprintf(SPEW, "getimage(): Loaded image [%s|%d]\n",
1552 info.images[loadedindex].name,
1553 info.images[loadedindex].imgsize);
Monika Singh292b3e92018-03-17 22:40:23 +05301554 return 0;
1555 }
1556 }
1557 return -1;
1558}
1559
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001560static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size)
1561{
1562 int ret;
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001563
1564#if !VERIFIED_BOOT
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001565#if IMAGE_VERIF_ALGO_SHA1
1566 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
1567#else
1568 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
1569#endif
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001570#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001571
1572 /* Assume device is rooted at this time. */
1573 device.is_tampered = 1;
1574
1575 dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
1576
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001577#if VERIFIED_BOOT
Monika Singh7d2fc272018-03-16 17:16:01 +05301578 uint32_t bootstate;
1579 if(boot_into_recovery &&
Mayank Grover68fbf0d2017-10-24 14:13:39 +05301580 (!partition_multislot_is_supported()))
Monika Singh7d2fc272018-03-16 17:16:01 +05301581 {
1582 ret = boot_verify_image((unsigned char *)bootimg_addr,
1583 bootimg_size, "/recovery", &bootstate);
1584 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001585 else
Monika Singh7d2fc272018-03-16 17:16:01 +05301586 {
1587 ret = boot_verify_image((unsigned char *)bootimg_addr,
1588 bootimg_size, "/boot", &bootstate);
1589 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001590 boot_verify_print_state();
1591#else
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001592 ret = image_verify((unsigned char *)bootimg_addr,
1593 (unsigned char *)(bootimg_addr + bootimg_size),
1594 bootimg_size,
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001595 auth_algo);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001596#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001597 dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret);
1598
1599 if (ret)
1600 {
1601 /* Authorized kernel */
1602 device.is_tampered = 0;
Sundarajan Srinivasan3fb21f12013-09-16 18:36:15 -07001603 auth_kernel_img = 1;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001604 }
1605
Amit Blay4aa292f2015-04-28 21:55:59 +03001606#ifdef MDTP_SUPPORT
1607 {
1608 /* Verify MDTP lock.
1609 * For boot & recovery partitions, use aboot's verification result.
1610 */
1611 mdtp_ext_partition_verification_t ext_partition;
1612 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
1613 ext_partition.integrity_state = device.is_tampered ? MDTP_PARTITION_STATE_INVALID : MDTP_PARTITION_STATE_VALID;
1614 ext_partition.page_size = 0; /* Not needed since already validated */
1615 ext_partition.image_addr = 0; /* Not needed since already validated */
1616 ext_partition.image_size = 0; /* Not needed since already validated */
1617 ext_partition.sig_avail = FALSE; /* Not needed since already validated */
1618 mdtp_fwlock_verify_lock(&ext_partition);
1619 }
1620#endif /* MDTP_SUPPORT */
1621
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001622#if USE_PCOM_SECBOOT
1623 set_tamper_flag(device.is_tampered);
1624#endif
1625
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001626#if VERIFIED_BOOT
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001627 switch(boot_verify_get_state())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001628 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001629 case RED:
lijuanga40d6302015-07-20 20:10:13 +08001630#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001631 display_bootverify_menu(DISPLAY_MENU_RED);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001632#if ENABLE_VB_ATTEST
1633 mdelay(DELAY_WAIT);
1634 shutdown_device();
1635#else
lijuanga40d6302015-07-20 20:10:13 +08001636 wait_for_users_action();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001637#endif
lijuanga40d6302015-07-20 20:10:13 +08001638#else
1639 dprintf(CRITICAL,
1640 "Your device has failed verification and may not work properly.\nWait for 5 seconds before proceeding\n");
1641 mdelay(5000);
1642#endif
1643
1644 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001645 case YELLOW:
lijuanga40d6302015-07-20 20:10:13 +08001646#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001647 display_bootverify_menu(DISPLAY_MENU_YELLOW);
lijuanga40d6302015-07-20 20:10:13 +08001648 wait_for_users_action();
1649#else
1650 dprintf(CRITICAL,
1651 "Your device has loaded a different operating system.\nWait for 5 seconds before proceeding\n");
1652 mdelay(5000);
1653#endif
1654 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001655 default:
lijuanga40d6302015-07-20 20:10:13 +08001656 break;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001657 }
1658#endif
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001659#if !VERIFIED_BOOT
Unnati Gandhi1be04752015-03-27 19:41:53 +05301660 if(device.is_tampered)
1661 {
1662 write_device_info_mmc(&device);
1663 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05301664 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Unnati Gandhi1be04752015-03-27 19:41:53 +05301665 #endif
1666 #ifdef ASSERT_ON_TAMPER
1667 dprintf(CRITICAL, "Device is tampered. Asserting..\n");
1668 ASSERT(0);
1669 #endif
1670 }
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001671#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001672}
1673
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301674static bool check_format_bit()
1675{
1676 bool ret = false;
1677 int index;
1678 uint64_t offset;
1679 struct boot_selection_info *in = NULL;
1680 char *buf = NULL;
1681
1682 index = partition_get_index("bootselect");
1683 if (index == INVALID_PTN)
1684 {
1685 dprintf(INFO, "Unable to locate /bootselect partition\n");
1686 return ret;
1687 }
1688 offset = partition_get_offset(index);
1689 if(!offset)
1690 {
1691 dprintf(INFO, "partition /bootselect doesn't exist\n");
1692 return ret;
1693 }
1694 buf = (char *) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE));
Mayank Grover48860402016-11-29 12:34:53 +05301695 mmc_set_lun(partition_get_lun(index));
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301696 ASSERT(buf);
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301697 if (mmc_read(offset, (uint32_t *)buf, page_size))
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301698 {
1699 dprintf(INFO, "mmc read failure /bootselect %d\n", page_size);
1700 free(buf);
1701 return ret;
1702 }
1703 in = (struct boot_selection_info *) buf;
1704 if ((in->signature == BOOTSELECT_SIGNATURE) &&
1705 (in->version == BOOTSELECT_VERSION)) {
1706 if ((in->state_info & BOOTSELECT_FORMAT) &&
1707 !(in->state_info & BOOTSELECT_FACTORY))
1708 ret = true;
1709 } else {
1710 dprintf(CRITICAL, "Signature: 0x%08x or version: 0x%08x mismatched of /bootselect\n",
1711 in->signature, in->version);
1712 ASSERT(0);
1713 }
1714 free(buf);
1715 return ret;
1716}
1717
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001718void boot_verifier_init()
1719{
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001720 uint32_t boot_state;
1721 /* Check if device unlock */
1722 if(device.is_unlocked)
1723 {
1724 boot_verify_send_event(DEV_UNLOCK);
1725 boot_verify_print_state();
1726 dprintf(CRITICAL, "Device is unlocked! Skipping verification...\n");
1727 return;
1728 }
1729 else
1730 {
1731 boot_verify_send_event(BOOT_INIT);
1732 }
1733
1734 /* Initialize keystore */
1735 boot_state = boot_verify_keystore_init();
1736 if(boot_state == YELLOW)
1737 {
1738 boot_verify_print_state();
1739 dprintf(CRITICAL, "Keystore verification failed! Continuing anyways...\n");
1740 }
1741}
1742
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301743/* Function to return recovery appended dtbo buffer info */
1744void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf)
1745{
1746 *dtbo_size = recovery_dtbo_size;
1747 *dtbo_buf = recovery_dtbo_buf;
1748 return;
1749}
1750
Shashank Mittal23b8f422010-04-16 19:27:21 -07001751int boot_linux_from_mmc(void)
1752{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301753 boot_img_hdr *hdr = (void*) buf;
1754 boot_img_hdr *uhdr;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001755 unsigned offset = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001756 int rcode;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001757 unsigned long long ptn = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07001758 int index = INVALID_PTN;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001759
Shashank Mittalcd98d472011-08-02 14:29:24 -07001760 unsigned char *image_addr = 0;
1761 unsigned kernel_actual;
1762 unsigned ramdisk_actual;
1763 unsigned imagesize_actual;
Neeti Desai465491e2012-07-31 12:53:35 -07001764 unsigned second_actual = 0;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301765 void * image_buf = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001766
Matthew Qin271927e2015-03-31 22:07:07 -04001767 unsigned int dtb_size = 0;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301768 unsigned dtb_image_size = 0;
1769 uint32_t dtb_image_offset = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001770 unsigned int out_len = 0;
1771 unsigned int out_avai_len = 0;
1772 unsigned char *out_addr = NULL;
1773 uint32_t dtb_offset = 0;
1774 unsigned char *kernel_start_addr = NULL;
1775 unsigned int kernel_size = 0;
Ameya Thakur10a33452016-06-13 14:24:26 -07001776 unsigned int patched_kernel_hdr_size = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301777 uint64_t image_size = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001778 int rc;
Monika Singh292b3e92018-03-17 22:40:23 +05301779#if VERIFIED_BOOT_2
1780 int status;
Mayank Grover027a9412018-09-04 15:12:05 +05301781 void *dtbo_image_buf = NULL;
1782 uint32_t dtbo_image_sz = 0;
Mayank Grover9df84c02018-08-30 15:46:35 +05301783 void *vbmeta_image_buf = NULL;
1784 uint32_t vbmeta_image_sz = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05301785#endif
Mayank Groverc93cad82017-10-03 12:23:45 +05301786 char *ptn_name = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001787#if DEVICE_TREE
1788 struct dt_table *table;
Joel Kingaa335dc2013-06-03 16:11:08 -07001789 struct dt_entry dt_entry;
Neeti Desai465491e2012-07-31 12:53:35 -07001790 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001791 uint32_t dt_actual;
Deepa Dinamani19648b42013-09-05 17:05:55 -07001792 uint32_t dt_hdr_size;
Matthew Qin271927e2015-03-31 22:07:07 -04001793 unsigned char *best_match_dt_addr = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001794#endif
Matthew Qin49e51fa2015-02-09 10:40:45 +08001795 struct kernel64_hdr *kptr = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05301796 int current_active_slot = INVALID;
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001797
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301798 if (check_format_bit())
1799 boot_into_recovery = 1;
1800
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001801 if (!boot_into_recovery) {
1802 memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string));
1803 rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string));
1804 if (rcode <= 0) {
1805 boot_into_ffbm = false;
1806 if (rcode < 0)
1807 dprintf(CRITICAL,"failed to get ffbm cookie");
1808 } else
1809 boot_into_ffbm = true;
1810 } else
1811 boot_into_ffbm = false;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301812 uhdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001813 if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
1814 dprintf(INFO, "Unified boot method!\n");
1815 hdr = uhdr;
1816 goto unified_boot;
1817 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301818
1819 /* For a/b recovery image code is on boot partition.
1820 If we support multislot, always use boot partition. */
1821 if (boot_into_recovery &&
Mayank Grover8ab4a762019-04-25 17:23:34 +05301822 ((!partition_multislot_is_supported()) ||
1823 (target_dynamic_partition_supported())))
Mayank Groverc93cad82017-10-03 12:23:45 +05301824 ptn_name = "recovery";
1825 else
1826 ptn_name = "boot";
1827
1828 index = partition_get_index(ptn_name);
1829 ptn = partition_get_offset(index);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301830 image_size = partition_get_size(index);
1831 if(ptn == 0 || image_size == 0) {
Mayank Groverc93cad82017-10-03 12:23:45 +05301832 dprintf(CRITICAL, "ERROR: No %s partition found\n", ptn_name);
1833 return -1;
Kinson Chikf1a43512011-07-14 11:28:39 -07001834 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301835
Channagoud Kadabief0547c2015-02-10 12:57:38 -08001836 /* Set Lun for boot & recovery partitions */
1837 mmc_set_lun(partition_get_lun(index));
Shashank Mittal23b8f422010-04-16 19:27:21 -07001838
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301839 if (mmc_read(ptn + offset, (uint32_t *) buf, page_size)) {
Shashank Mittal23b8f422010-04-16 19:27:21 -07001840 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
1841 return -1;
1842 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07001843
1844 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07001845 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Mayank Grover351a75e2017-05-30 20:06:08 +05301846 return ERR_INVALID_BOOT_MAGIC;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001847 }
1848
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001849 if (hdr->page_size && (hdr->page_size != page_size)) {
vijay kumar2e21b3a2014-06-26 17:40:15 +05301850
1851 if (hdr->page_size > BOOT_IMG_MAX_PAGE_SIZE) {
1852 dprintf(CRITICAL, "ERROR: Invalid page size\n");
1853 return -1;
1854 }
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001855 page_size = hdr->page_size;
1856 page_mask = page_size - 1;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001857 }
1858
Matthew Qin49e51fa2015-02-09 10:40:45 +08001859 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1860 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301861 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001862
Matthew Qin49e51fa2015-02-09 10:40:45 +08001863 image_addr = (unsigned char *)target_get_scratch_address();
Mayank Grover6fd36792018-09-10 13:26:58 +05301864#if VERIFIED_BOOT_2
1865 /* Create hole in start of image for VB salt to copy */
1866 image_addr += SALT_BUFF_OFFSET;
1867#endif
Kishor PK9e91b592017-05-24 12:14:55 +05301868 memcpy(image_addr, (void *)buf, page_size);
1869
1870 /* ensure commandline is terminated */
1871 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001872
1873#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05301874#ifndef OSVERSION_IN_BOOTIMAGE
1875 dt_size = hdr->dt_size;
Mayank Grover5a502582018-09-12 11:24:49 +05301876#else
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301877 dprintf(INFO, "BootImage Header: %d\n", hdr->header_version);
Mayank Grover5a502582018-09-12 11:24:49 +05301878#endif
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301879
Parth Dixit4097b622016-03-15 14:42:27 +05301880 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301881 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 +05301882 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1883 return -1;
1884 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301885 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001886#else
Kishor PKd8ddcad2017-07-27 13:53:57 +05301887 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 +05301888 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1889 return -1;
1890 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301891 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001892#endif
Parth Dixit1375d9e2019-07-08 20:56:13 +05301893 dtb_image_size = hdr->kernel_size;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001894
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301895#ifdef OSVERSION_IN_BOOTIMAGE
1896 /* If header version is ONE and booting into recovery,
1897 dtbo is appended with recovery image.
1898 Doing following:
1899 * Validating the recovery offset and size.
1900 * Extracting recovery dtbo to be used as dtbo.
1901 */
1902 if (boot_into_recovery &&
1903 hdr->header_version == BOOT_HEADER_VERSION_ONE)
1904 {
1905 struct boot_img_hdr_v1 *hdr1 =
1906 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
Mayank Grovera1a83c72018-09-24 11:23:15 +05301907 unsigned int recovery_dtbo_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301908
Mayank Grovera1a83c72018-09-24 11:23:15 +05301909 recovery_dtbo_actual = ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301910 if ((hdr1->header_size !=
1911 sizeof(struct boot_img_hdr_v1) + sizeof(boot_img_hdr)))
1912 {
1913 dprintf(CRITICAL, "Invalid boot image header: %d\n", hdr1->header_size);
1914 return -1;
1915 }
1916
Mayank Grovera1a83c72018-09-24 11:23:15 +05301917 if (recovery_dtbo_actual > MAX_SUPPORTED_DTBO_IMG_BUF)
1918 {
1919 dprintf(CRITICAL, "Recovery Dtbo Size too big %x, Allowed size %x\n", recovery_dtbo_actual,
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301920 MAX_SUPPORTED_DTBO_IMG_BUF);
1921 return -1;
1922 }
1923
Mayank Grovera1a83c72018-09-24 11:23:15 +05301924 if (UINT_MAX < ((uint64_t)imagesize_actual + recovery_dtbo_actual))
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301925 {
1926 dprintf(CRITICAL, "Integer overflow detected in recoveryimage header fields at %u in %s\n",__LINE__,__FILE__);
1927 return -1;
1928 }
1929
Mayank Grovera1a83c72018-09-24 11:23:15 +05301930 if (UINT_MAX < (hdr1->recovery_dtbo_offset + recovery_dtbo_actual)) {
1931 dprintf(CRITICAL,
1932 "Integer overflow detected in recovery image header fields at %u in %s\n",__LINE__,__FILE__);
1933 return -1;
1934 }
1935
1936 if (hdr1->recovery_dtbo_offset + recovery_dtbo_actual > image_size)
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301937 {
1938 dprintf(CRITICAL, "Invalid recovery dtbo: Recovery Dtbo Offset=0x%llx,"
1939 " Recovery Dtbo Size=0x%x, Image Size=0x%llx\n",
1940 hdr1->recovery_dtbo_offset, recovery_dtbo_size, image_size);
1941 return -1;
1942 }
1943
1944 recovery_dtbo_buf = (void *)(hdr1->recovery_dtbo_offset + image_addr);
Mayank Grovera1a83c72018-09-24 11:23:15 +05301945 recovery_dtbo_size = recovery_dtbo_actual;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301946 imagesize_actual += recovery_dtbo_size;
1947
1948 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
1949 dprintf(SPEW, "Recovery Dtbo Size 0x%x\n", recovery_dtbo_size);
1950 dprintf(SPEW, "Recovery Dtbo Offset 0x%llx\n", hdr1->recovery_dtbo_offset);
1951
1952 }
Parth Dixit1375d9e2019-07-08 20:56:13 +05301953
1954 if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
1955 struct boot_img_hdr_v1 *hdr1 =
1956 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
1957 struct boot_img_hdr_v2 *hdr2 = (struct boot_img_hdr_v2 *)
1958 (image_addr + sizeof(boot_img_hdr) +
1959 BOOT_IMAGE_HEADER_V2_OFFSET);
1960 unsigned int recovery_dtbo_actual = 0;
1961
lijuang0b17ba22019-09-04 14:20:47 +08001962 recovery_dtbo_actual =
1963 ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
1964 imagesize_actual += recovery_dtbo_actual;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301965
1966 imagesize_actual += ROUND_TO_PAGE(hdr2->dtb_size, page_mask);
1967
1968
1969 dtb_image_offset = page_size + patched_kernel_hdr_size +
1970 kernel_actual + ramdisk_actual + second_actual +
1971 recovery_dtbo_actual;
1972
1973 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
1974 dprintf(SPEW, "Dtb image offset 0x%x\n", dtb_image_offset);
1975 }
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301976#endif
1977
Parth Dixit1375d9e2019-07-08 20:56:13 +05301978
Saranya Chidurab1aaf232018-11-19 15:47:50 +05301979 /* Validate the boot/recovery image size is within the bounds of partition size */
1980 if (imagesize_actual > image_size) {
1981 dprintf(CRITICAL, "Image size is greater than partition size.\n");
1982 return -1;
1983 }
1984
Matthew Qin49e51fa2015-02-09 10:40:45 +08001985#if VERIFIED_BOOT
1986 boot_verifier_init();
1987#endif
1988
Mayank Grover1ceaee22019-04-01 17:54:32 +05301989#if VERIFIED_BOOT_2
1990 /* read full partition if device is unlocked */
1991 if (device.is_unlocked)
1992 imagesize_actual = image_size;
1993#endif
1994
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301995 if (check_aboot_addr_range_overlap((uintptr_t) image_addr, imagesize_actual))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001996 {
1997 dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
1998 return -1;
1999 }
2000
Matthew Qinbb7923d2015-02-09 10:56:09 +08002001 /*
2002 * Update loading flow of bootimage to support compressed/uncompressed
2003 * bootimage on both 64bit and 32bit platform.
2004 * 1. Load bootimage from emmc partition onto DDR.
2005 * 2. Check if bootimage is gzip format. If yes, decompress compressed kernel
2006 * 3. Check kernel header and update kernel load addr for 64bit and 32bit
2007 * platform accordingly.
2008 * 4. Sanity Check on kernel_addr and ramdisk_addr and copy data.
2009 */
Mayank Grover351a75e2017-05-30 20:06:08 +05302010 if (partition_multislot_is_supported())
2011 {
2012 current_active_slot = partition_find_active_slot();
2013 dprintf(INFO, "Loading boot image (%d) active_slot(%s): start\n",
2014 imagesize_actual, SUFFIX_SLOT(current_active_slot));
2015 }
2016 else
2017 {
2018 dprintf(INFO, "Loading (%s) image (%d): start\n",
2019 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2020 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002021 bs_set_timestamp(BS_KERNEL_LOAD_START);
2022
Gaurav Nebhwani43e2a462016-03-17 21:32:56 +05302023 if ((target_get_max_flash_size() - page_size) < imagesize_actual)
2024 {
2025 dprintf(CRITICAL, "booimage size is greater than DDR can hold\n");
2026 return -1;
2027 }
Kishor PK9e91b592017-05-24 12:14:55 +05302028 offset = page_size;
2029 /* Read image without signature and header*/
2030 if (mmc_read(ptn + offset, (void *)(image_addr + offset), imagesize_actual - page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08002031 {
2032 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
2033 return -1;
2034 }
2035
Mayank Grover351a75e2017-05-30 20:06:08 +05302036 if (partition_multislot_is_supported())
2037 {
2038 dprintf(INFO, "Loading boot image (%d) active_slot(%s): done\n",
2039 imagesize_actual, SUFFIX_SLOT(current_active_slot));
2040 }
2041 else
2042 {
2043 dprintf(INFO, "Loading (%s) image (%d): done\n",
Channagoud Kadabif0705b52015-08-20 14:16:08 -07002044 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2045
Mayank Grover351a75e2017-05-30 20:06:08 +05302046 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002047 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
2048
2049 /* Authenticate Kernel */
2050 dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
2051 (int) target_use_signed_kernel(),
2052 device.is_unlocked,
2053 device.is_tampered);
Monika Singh292b3e92018-03-17 22:40:23 +05302054#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05302055 /* if device is unlocked skip reading signature, as full partition is read */
2056 if (!device.is_unlocked)
Monika Singh292b3e92018-03-17 22:40:23 +05302057 {
Mayank Grover1ceaee22019-04-01 17:54:32 +05302058 offset = imagesize_actual;
2059 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
2060 {
2061 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
2062 return -1;
2063 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002064
Mayank Grover1ceaee22019-04-01 17:54:32 +05302065 /* Read signature */
2066 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
2067 {
2068 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
2069 return -1;
2070 }
Monika Singh292b3e92018-03-17 22:40:23 +05302071 }
2072
Mayank Grover027a9412018-09-04 15:12:05 +05302073 /* load and validate dtbo partition */
2074 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
2075
Mayank Grover9df84c02018-08-30 15:46:35 +05302076 /* load vbmeta partition */
2077 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
2078
Monika Singh292b3e92018-03-17 22:40:23 +05302079 memset(&info, 0, sizeof(bootinfo));
Mayank Grover027a9412018-09-04 15:12:05 +05302080
2081 /* Pass loaded boot image passed */
Mayank Grover6fd36792018-09-10 13:26:58 +05302082 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(image_addr);
Mayank Grover027a9412018-09-04 15:12:05 +05302083 info.images[IMG_BOOT].imgsize = imagesize_actual;
2084 info.images[IMG_BOOT].name = ptn_name;
2085 ++info.num_loaded_images;
2086
2087 /* Pass loaded dtbo image */
2088 if (dtbo_image_buf != NULL) {
Mayank Grover6fd36792018-09-10 13:26:58 +05302089 info.images[IMG_DTBO].image_buffer =
2090 SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
Mayank Grover027a9412018-09-04 15:12:05 +05302091 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
2092 info.images[IMG_DTBO].name = "dtbo";
2093 ++info.num_loaded_images;
2094 }
2095
Mayank Grover9df84c02018-08-30 15:46:35 +05302096 /* Pass loaded vbmeta image */
2097 if (vbmeta_image_buf != NULL) {
2098 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
2099 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
2100 info.images[IMG_VBMETA].name = "vbmeta";
2101 ++info.num_loaded_images;
2102 }
2103
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302104 info.header_version = hdr->header_version;
Monika Singh292b3e92018-03-17 22:40:23 +05302105 info.multi_slot_boot = partition_multislot_is_supported();
2106 info.bootreason_alarm = boot_reason_alarm;
2107 info.bootinto_recovery = boot_into_recovery;
2108 status = load_image_and_auth(&info);
2109 if(status)
2110 return -1;
2111
2112 vbcmdline = info.vbcmdline;
Mayank Grover9df84c02018-08-30 15:46:35 +05302113
2114 /* Free the buffer allocated to vbmeta post verification */
Saranya Chidurab4933332018-10-15 17:30:06 +05302115 if (vbmeta_image_buf != NULL) {
2116 free(vbmeta_image_buf);
2117 --info.num_loaded_images;
2118 }
Monika Singh292b3e92018-03-17 22:40:23 +05302119#else
Channagoud Kadabi736c4962015-08-21 11:56:52 -07002120 /* Change the condition a little bit to include the test framework support.
2121 * We would never reach this point if device is in fastboot mode, even if we did
2122 * that means we are in test mode, so execute kernel authentication part for the
2123 * tests */
Parth Dixitcb0c6082015-12-30 15:01:13 +05302124 if((target_use_signed_kernel() && (!device.is_unlocked)) || is_test_mode_enabled())
Matthew Qin49e51fa2015-02-09 10:40:45 +08002125 {
2126 offset = imagesize_actual;
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05302127 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08002128 {
2129 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
2130 return -1;
2131 }
2132
2133 /* Read signature */
2134 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
2135 {
2136 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
2137 return -1;
2138 }
2139
2140 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Channagoud Kadabi736c4962015-08-21 11:56:52 -07002141 /* The purpose of our test is done here */
Parth Dixitcb0c6082015-12-30 15:01:13 +05302142 if(is_test_mode_enabled() && auth_kernel_img)
Channagoud Kadabi736c4962015-08-21 11:56:52 -07002143 return 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08002144 } else {
2145 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
2146 #ifdef TZ_SAVE_KERNEL_HASH
2147 aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
2148 #endif /* TZ_SAVE_KERNEL_HASH */
Amit Blay4aa292f2015-04-28 21:55:59 +03002149
2150#ifdef MDTP_SUPPORT
2151 {
2152 /* Verify MDTP lock.
2153 * For boot & recovery partitions, MDTP will use boot_verifier APIs,
2154 * since verification was skipped in aboot. The signature is not part of the loaded image.
2155 */
2156 mdtp_ext_partition_verification_t ext_partition;
2157 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
2158 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
2159 ext_partition.page_size = page_size;
2160 ext_partition.image_addr = (uint32)image_addr;
2161 ext_partition.image_size = imagesize_actual;
2162 ext_partition.sig_avail = FALSE;
2163 mdtp_fwlock_verify_lock(&ext_partition);
2164 }
2165#endif /* MDTP_SUPPORT */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002166 }
Monika Singh292b3e92018-03-17 22:40:23 +05302167#endif
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002168
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -07002169#if VERIFIED_BOOT
taozhang93088bd2016-11-16 15:50:46 +08002170 if((boot_verify_get_state() == ORANGE) && (!boot_into_ffbm))
Reut Zysmanba8a9d52016-02-18 11:44:04 +02002171 {
2172#if FBCON_DISPLAY_MSG
2173 display_bootverify_menu(DISPLAY_MENU_ORANGE);
2174 wait_for_users_action();
2175#else
2176 dprintf(CRITICAL,
2177 "Your device has been unlocked and can't be trusted.\nWait for 5 seconds before proceeding\n");
2178 mdelay(5000);
2179#endif
2180 }
2181#endif
2182
2183#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05302184 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302185 {
2186 /* set boot and system versions. */
2187 set_os_version((unsigned char *)image_addr);
2188 // send root of trust
2189 if(!send_rot_command((uint32_t)device.is_unlocked))
2190 ASSERT(0);
2191 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05302192#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002193 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08002194 * Check if the kernel image is a gzip package. If yes, need to decompress it.
2195 * If not, continue booting.
2196 */
2197 if (is_gzip_package((unsigned char *)(image_addr + page_size), hdr->kernel_size))
2198 {
2199 out_addr = (unsigned char *)(image_addr + imagesize_actual + page_size);
2200 out_avai_len = target_get_max_flash_size() - imagesize_actual - page_size;
Mayank Grover027a9412018-09-04 15:12:05 +05302201#if VERIFIED_BOOT_2
2202 if (dtbo_image_sz)
2203 out_avai_len -= DTBO_IMG_BUF;
2204#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04002205 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08002206 rc = decompress((unsigned char *)(image_addr + page_size),
2207 hdr->kernel_size, out_addr, out_avai_len,
2208 &dtb_offset, &out_len);
2209 if (rc)
2210 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002211 dprintf(CRITICAL, "decompressing kernel image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08002212 ASSERT(0);
2213 }
2214
Matthew Qin0b15b322015-05-19 05:20:54 -04002215 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08002216 kptr = (struct kernel64_hdr *)out_addr;
2217 kernel_start_addr = out_addr;
2218 kernel_size = out_len;
2219 } else {
Ameya Thakur10a33452016-06-13 14:24:26 -07002220 dprintf(INFO, "Uncpmpressed kernel in use\n");
2221 if (!strncmp((char*)(image_addr + page_size),
2222 PATCHED_KERNEL_MAGIC,
2223 sizeof(PATCHED_KERNEL_MAGIC) - 1)) {
2224 dprintf(INFO, "Patched kernel detected\n");
2225 kptr = (struct kernel64_hdr *)(image_addr + page_size +
2226 PATCHED_KERNEL_HEADER_SIZE);
2227 //The size of the kernel is stored at start of kernel image + 16
2228 //The dtb would start just after the kernel
2229 dtb_offset = *((uint32_t*)((unsigned char*)
2230 (image_addr + page_size +
2231 sizeof(PATCHED_KERNEL_MAGIC) -
2232 1)));
2233 //The actual kernel starts after the 20 byte header.
2234 kernel_start_addr = (unsigned char*)(image_addr +
2235 page_size + PATCHED_KERNEL_HEADER_SIZE);
2236 kernel_size = hdr->kernel_size;
2237 patched_kernel_hdr_size = PATCHED_KERNEL_HEADER_SIZE;
2238 } else {
2239 dprintf(INFO, "Kernel image not patched..Unable to locate dt offset\n");
2240 kptr = (struct kernel64_hdr *)(image_addr + page_size);
2241 kernel_start_addr = (unsigned char *)(image_addr + page_size);
2242 kernel_size = hdr->kernel_size;
2243 }
Matthew Qinbb7923d2015-02-09 10:56:09 +08002244 }
2245
2246 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002247 * Update the kernel/ramdisk/tags address if the boot image header
2248 * has default values, these default values come from mkbootimg when
2249 * the boot image is flashed using fastboot flash:raw
2250 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002251 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002252
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002253 /* Get virtual addresses since the hdr saves physical addresses. */
2254 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
2255 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
2256 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002257
Matthew Qinbb7923d2015-02-09 10:56:09 +08002258 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002259 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08002260 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05302261 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
2262 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
2263 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002264 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302265 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002266 return -1;
2267 }
2268
2269#ifndef DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05302270 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2271 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002272 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302273 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002274 return -1;
2275 }
2276#endif
2277
Matthew Qin49e51fa2015-02-09 10:40:45 +08002278 /* Move kernel, ramdisk and device tree to correct address */
Matthew Qinbb7923d2015-02-09 10:56:09 +08002279 memmove((void*) hdr->kernel_addr, kernel_start_addr, kernel_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002280 memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07002281
Matthew Qin49e51fa2015-02-09 10:40:45 +08002282 #if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05302283 if(dt_size) {
Matthew Qin49e51fa2015-02-09 10:40:45 +08002284 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2285 table = (struct dt_table*) dt_table_offset;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002286
Matthew Qin49e51fa2015-02-09 10:40:45 +08002287 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2288 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2289 return -1;
2290 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002291
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302292 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2293 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05302294 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302295 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2296 return -1;
2297 }
2298
Matthew Qin49e51fa2015-02-09 10:40:45 +08002299 /* Find index of device tree within device tree table */
2300 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2301 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2302 return -1;
2303 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002304
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05302305 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2306 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2307 return -1;
2308 }
2309
2310 /* Ensure we are not overshooting dt_size with the dt_entry selected */
Parth Dixit4097b622016-03-15 14:42:27 +05302311 if ((dt_entry.offset + dt_entry.size) > dt_size) {
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05302312 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2313 return -1;
2314 }
2315
Matthew Qin271927e2015-03-31 22:07:07 -04002316 if (is_gzip_package((unsigned char *)dt_table_offset + dt_entry.offset, dt_entry.size))
2317 {
2318 unsigned int compressed_size = 0;
2319 out_addr += out_len;
2320 out_avai_len -= out_len;
Matthew Qin0b15b322015-05-19 05:20:54 -04002321 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002322 rc = decompress((unsigned char *)dt_table_offset + dt_entry.offset,
2323 dt_entry.size, out_addr, out_avai_len,
2324 &compressed_size, &dtb_size);
2325 if (rc)
2326 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002327 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002328 ASSERT(0);
2329 }
2330
Matthew Qin0b15b322015-05-19 05:20:54 -04002331 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002332 best_match_dt_addr = out_addr;
2333 } else {
2334 best_match_dt_addr = (unsigned char *)dt_table_offset + dt_entry.offset;
2335 dtb_size = dt_entry.size;
2336 }
2337
Matthew Qin49e51fa2015-02-09 10:40:45 +08002338 /* Validate and Read device device tree in the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302339 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
2340 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002341 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302342 dprintf(CRITICAL, "Device tree addresses are not valid\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002343 return -1;
2344 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002345
Matthew Qin271927e2015-03-31 22:07:07 -04002346 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002347 } else {
2348 /* Validate the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302349 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2350 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002351 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302352 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002353 return -1;
2354 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002355 /*
2356 * If appended dev tree is found, update the atags with
2357 * memory address to the DTB appended location on RAM.
2358 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302359 *
2360 * Make sure everything from scratch address is read before next step!
2361 * In case of dtbo, this API is going to read dtbo on scratch.
Matthew Qin49e51fa2015-02-09 10:40:45 +08002362 */
2363 void *dtb;
Parth Dixit1375d9e2019-07-08 20:56:13 +05302364 image_buf = (void*)(image_addr + page_size + patched_kernel_hdr_size);
2365
Nagireddy Annem0d60bb62019-08-16 19:16:00 +05302366#ifdef OSVERSION_IN_BOOTIMAGE
Parth Dixit1375d9e2019-07-08 20:56:13 +05302367 if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
2368
2369 image_buf = (void*)(image_addr);
2370 dtb_offset = dtb_image_offset;
2371 dtb_image_size = imagesize_actual;
2372 }
Nagireddy Annem0d60bb62019-08-16 19:16:00 +05302373#endif
Parth Dixit1375d9e2019-07-08 20:56:13 +05302374
2375 dtb = dev_tree_appended(image_buf, dtb_image_size, dtb_offset,
Ameya Thakur10a33452016-06-13 14:24:26 -07002376 (void *)hdr->tags_addr);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002377 if (!dtb) {
2378 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002379 return -1;
2380 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002381 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002382 #endif
Shashank Mittal23b8f422010-04-16 19:27:21 -07002383
Stanimir Varbanov69ec5462013-07-18 18:17:42 +03002384 if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
2385 target_load_ssd_keystore();
2386
Shashank Mittal23b8f422010-04-16 19:27:21 -07002387unified_boot:
Shashank Mittal23b8f422010-04-16 19:27:21 -07002388
Dima Zavin77e41f32013-03-06 16:10:43 -08002389 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002390 (const char *)hdr->cmdline, board_machtype(),
Shashank Mittal23b8f422010-04-16 19:27:21 -07002391 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2392
2393 return 0;
2394}
2395
Dima Zavin214cc642009-01-26 11:16:21 -08002396int boot_linux_from_flash(void)
2397{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302398 boot_img_hdr *hdr = (void*) buf;
Dima Zavin214cc642009-01-26 11:16:21 -08002399 struct ptentry *ptn;
2400 struct ptable *ptable;
2401 unsigned offset = 0;
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002402
Shashank Mittalcd98d472011-08-02 14:29:24 -07002403 unsigned char *image_addr = 0;
2404 unsigned kernel_actual;
2405 unsigned ramdisk_actual;
2406 unsigned imagesize_actual;
vijay kumar8f53e362015-11-24 13:38:11 +05302407 unsigned second_actual = 0;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002408
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002409#if DEVICE_TREE
Monika Singh292b3e92018-03-17 22:40:23 +05302410 struct dt_table *table = NULL;
Joel Kingaa335dc2013-06-03 16:11:08 -07002411 struct dt_entry dt_entry;
vijay kumar8f53e362015-11-24 13:38:11 +05302412 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08002413 uint32_t dt_actual;
Monika Singh292b3e92018-03-17 22:40:23 +05302414 uint32_t dt_hdr_size = 0;
Vivek Kumar07bd0862018-04-10 14:19:23 +05302415 uint32_t dtb_offset = 0;
vijay kumar8f53e362015-11-24 13:38:11 +05302416 unsigned int dtb_size = 0;
2417 unsigned char *best_match_dt_addr = NULL;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002418#endif
2419
David Ng183a7422009-12-07 14:55:21 -08002420 if (target_is_emmc_boot()) {
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302421 hdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
David Ng183a7422009-12-07 14:55:21 -08002422 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
2423 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
2424 return -1;
2425 }
2426 goto continue_boot;
2427 }
2428
Dima Zavin214cc642009-01-26 11:16:21 -08002429 ptable = flash_get_ptable();
2430 if (ptable == NULL) {
2431 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2432 return -1;
2433 }
2434
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002435 if(!boot_into_recovery)
2436 {
2437 ptn = ptable_find(ptable, "boot");
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002438
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002439 if (ptn == NULL) {
2440 dprintf(CRITICAL, "ERROR: No boot partition found\n");
2441 return -1;
2442 }
2443 }
2444 else
2445 {
2446 ptn = ptable_find(ptable, "recovery");
2447 if (ptn == NULL) {
2448 dprintf(CRITICAL, "ERROR: No recovery partition found\n");
2449 return -1;
2450 }
Dima Zavin214cc642009-01-26 11:16:21 -08002451 }
2452
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302453 /* Read boot.img header from flash */
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002454 if (flash_read(ptn, offset, buf, page_size)) {
Dima Zavin214cc642009-01-26 11:16:21 -08002455 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
2456 return -1;
2457 }
Dima Zavin214cc642009-01-26 11:16:21 -08002458
2459 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002460 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Dima Zavin214cc642009-01-26 11:16:21 -08002461 return -1;
2462 }
2463
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002464 if (hdr->page_size != page_size) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002465 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 -08002466 return -1;
2467 }
2468
Kishor PK9e91b592017-05-24 12:14:55 +05302469 image_addr = (unsigned char *)target_get_scratch_address();
2470 memcpy(image_addr, (void *)buf, page_size);
vijay kumar287bb542015-09-29 13:01:52 +05302471
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002472 /*
2473 * Update the kernel/ramdisk/tags address if the boot image header
2474 * has default values, these default values come from mkbootimg when
2475 * the boot image is flashed using fastboot flash:raw
2476 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002477 update_ker_tags_rdisk_addr(hdr, false);
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002478
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002479 /* Get virtual addresses since the hdr saves physical addresses. */
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002480 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
2481 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
2482 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
2483
2484 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
2485 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Mayank Grover032736f2017-07-14 20:34:51 +05302486 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002487
Kishor PK9e91b592017-05-24 12:14:55 +05302488 /* ensure commandline is terminated */
2489 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
2490
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002491 /* Check if the addresses in the header are valid. */
2492 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05302493 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_actual) ||
2494 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
2495 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002496 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302497 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002498 return -1;
2499 }
2500
2501#ifndef DEVICE_TREE
Kishor PKd8ddcad2017-07-27 13:53:57 +05302502 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + page_size)) {
Mayank Grover032736f2017-07-14 20:34:51 +05302503 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2504 return -1;
2505 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05302506 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302507
Mayank Grovere559cec2017-10-17 15:12:03 +05302508 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2509 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302510 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302511 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302512 return -1;
2513 }
2514#else
2515
2516#ifndef OSVERSION_IN_BOOTIMAGE
2517 dt_size = hdr->dt_size;
2518#endif
Mayank Grover032736f2017-07-14 20:34:51 +05302519 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05302520 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 +05302521 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2522 return -1;
2523 }
2524
Kishor PKd8ddcad2017-07-27 13:53:57 +05302525 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302526
Mayank Grovere559cec2017-10-17 15:12:03 +05302527 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size) ||
2528 check_ddr_addr_range_bound(hdr->tags_addr, dt_size))
Mayank Grover032736f2017-07-14 20:34:51 +05302529 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302530 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Mayank Grover032736f2017-07-14 20:34:51 +05302531 return -1;
2532 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002533#endif
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002534
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302535 /* Read full boot.img from flash */
2536 dprintf(INFO, "Loading (%s) image (%d): start\n",
2537 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2538 bs_set_timestamp(BS_KERNEL_LOAD_START);
2539
2540 if (UINT_MAX - page_size < imagesize_actual)
2541 {
2542 dprintf(CRITICAL,"Integer overflow detected in bootimage header fields %u %s\n", __LINE__,__func__);
2543 return -1;
2544 }
2545
2546 /*Check the availability of RAM before reading boot image + max signature length from flash*/
2547 if (target_get_max_flash_size() < (imagesize_actual + page_size))
2548 {
2549 dprintf(CRITICAL, "bootimage size is greater than DDR can hold\n");
2550 return -1;
2551 }
2552
2553 offset = page_size;
2554 /* Read image without signature and header */
2555 if (flash_read(ptn, offset, (void *)(image_addr + offset), imagesize_actual - page_size))
2556 {
2557 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
2558 return -1;
2559 }
2560
2561 dprintf(INFO, "Loading (%s) image (%d): done\n",
2562 (!boot_into_recovery ? "boot" : "recovery"), imagesize_actual);
2563 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
2564
Shashank Mittalcd98d472011-08-02 14:29:24 -07002565 /* Authenticate Kernel */
Deepa Dinamani23b60d42013-06-24 18:10:52 -07002566 if(target_use_signed_kernel() && (!device.is_unlocked))
Shashank Mittalcd98d472011-08-02 14:29:24 -07002567 {
Shashank Mittalcd98d472011-08-02 14:29:24 -07002568 offset = imagesize_actual;
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302569
Shashank Mittalcd98d472011-08-02 14:29:24 -07002570 /* Read signature */
2571 if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
2572 {
2573 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002574 return -1;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002575 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002576
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05302577 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302578 }
2579 offset = page_size;
2580 if(hdr->second_size != 0) {
2581 if (UINT_MAX - offset < second_actual)
2582 {
2583 dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
2584 return -1;
vijay kumar8f53e362015-11-24 13:38:11 +05302585 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302586 offset += second_actual;
2587 /* Second image loading not implemented. */
2588 ASSERT(0);
2589 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302590 /* Move kernel and ramdisk to correct address */
2591 memmove((void*) hdr->kernel_addr, (char*) (image_addr + page_size), hdr->kernel_size);
2592 memmove((void*) hdr->ramdisk_addr, (char*) (image_addr + page_size + kernel_actual), hdr->ramdisk_size);
2593
2594#if DEVICE_TREE
2595 if(dt_size != 0) {
2596
2597 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2598
2599 table = (struct dt_table*) dt_table_offset;
2600
2601 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2602 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2603 return -1;
2604 }
2605
2606 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2607 goes beyound hdr->dt_size*/
2608 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
2609 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2610 return -1;
2611 }
2612
2613 /* Find index of device tree within device tree table */
2614 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2615 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2616 return -1;
2617 }
2618
2619 /* Validate and Read device device tree in the "tags_add */
2620 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size) ||
2621 check_ddr_addr_range_bound(hdr->tags_addr, dt_entry.size))
2622 {
2623 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2624 return -1;
2625 }
2626
2627 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2628 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2629 return -1;
2630 }
2631
2632 /* Ensure we are not overshooting dt_size with the dt_entry selected */
2633 if ((dt_entry.offset + dt_entry.size) > dt_size) {
2634 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2635 return -1;
2636 }
2637
2638 best_match_dt_addr = (unsigned char *)table + dt_entry.offset;
2639 dtb_size = dt_entry.size;
2640 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Vivek Kumar07bd0862018-04-10 14:19:23 +05302641
2642 } else {
2643 /* Validate the tags_addr */
2644 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2645 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
2646 {
2647 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2648 return -1;
2649 }
2650 /*
2651 * If appended dev tree is found, update the atags with
2652 * memory address to the DTB appended location on RAM.
2653 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302654 *
2655 * Make sure everything from scratch address is read before next step!
2656 * In case of dtbo, this API is going to read dtbo on scratch.
Vivek Kumar07bd0862018-04-10 14:19:23 +05302657 */
2658 void *dtb = NULL;
2659 dtb = dev_tree_appended((void*)(image_addr + page_size ),hdr->kernel_size, dtb_offset, (void *)hdr->tags_addr);
2660 if (!dtb) {
2661 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
2662 return -1;
2663 }
2664 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302665#endif
2666 if(target_use_signed_kernel() && (!device.is_unlocked))
2667 {
Shashank Mittal162244e2011-08-08 19:01:25 -07002668 /* Make sure everything from scratch address is read before next step!*/
Shashank Mittala0032282011-08-26 14:50:11 -07002669 if(device.is_tampered)
Shashank Mittal162244e2011-08-08 19:01:25 -07002670 {
2671 write_device_info_flash(&device);
2672 }
Channagoud Kadabi5c86fe32012-02-16 10:58:48 +05302673#if USE_PCOM_SECBOOT
2674 set_tamper_flag(device.is_tampered);
2675#endif
Shashank Mittalcd98d472011-08-02 14:29:24 -07002676 }
David Ng183a7422009-12-07 14:55:21 -08002677continue_boot:
Dima Zavin214cc642009-01-26 11:16:21 -08002678
Dima Zavin214cc642009-01-26 11:16:21 -08002679 /* TODO: create/pass atags to kernel */
2680
Ajay Dudanie28a6072011-07-01 13:59:46 -07002681 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002682 (const char *)hdr->cmdline, board_machtype(),
Dima Zavin214cc642009-01-26 11:16:21 -08002683 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2684
2685 return 0;
2686}
Brian Swetland9c4c0752009-01-25 16:23:50 -08002687
Shashank Mittal162244e2011-08-08 19:01:25 -07002688void write_device_info_mmc(device_info *dev)
2689{
Shashank Mittal162244e2011-08-08 19:01:25 -07002690 unsigned long long ptn = 0;
2691 unsigned long long size;
2692 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002693 uint8_t lun = 0;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002694 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302695 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002696
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002697 if (devinfo_present)
2698 index = partition_get_index("devinfo");
2699 else
2700 index = partition_get_index("aboot");
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002701
Shashank Mittal162244e2011-08-08 19:01:25 -07002702 ptn = partition_get_offset(index);
2703 if(ptn == 0)
2704 {
2705 return;
2706 }
2707
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002708 lun = partition_get_lun(index);
2709 mmc_set_lun(lun);
2710
Shashank Mittal162244e2011-08-08 19:01:25 -07002711 size = partition_get_size(index);
2712
Mayank Groverddd348d2018-01-23 14:07:09 +05302713 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2714 mmc_blocksize_mask);
2715 if (device_info_sz == UINT_MAX)
2716 {
2717 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2718 return;
2719 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002720
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002721 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302722 ret = mmc_write(ptn, device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002723 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302724 ret = mmc_write((ptn + size - device_info_sz), device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002725 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002726 {
2727 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002728 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002729 }
2730}
2731
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002732void read_device_info_mmc(struct device_info *info)
Shashank Mittal162244e2011-08-08 19:01:25 -07002733{
Shashank Mittal162244e2011-08-08 19:01:25 -07002734 unsigned long long ptn = 0;
2735 unsigned long long size;
2736 int index = INVALID_PTN;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002737 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302738 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002739
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002740 if ((index = partition_get_index("devinfo")) < 0)
2741 {
2742 devinfo_present = false;
2743 index = partition_get_index("aboot");
2744 }
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002745
Shashank Mittal162244e2011-08-08 19:01:25 -07002746 ptn = partition_get_offset(index);
2747 if(ptn == 0)
2748 {
2749 return;
2750 }
2751
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002752 mmc_set_lun(partition_get_lun(index));
2753
Shashank Mittal162244e2011-08-08 19:01:25 -07002754 size = partition_get_size(index);
2755
Mayank Groverddd348d2018-01-23 14:07:09 +05302756 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2757 mmc_blocksize_mask);
2758 if (device_info_sz == UINT_MAX)
2759 {
2760 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2761 return;
2762 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002763
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002764 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302765 ret = mmc_read(ptn, (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002766 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302767 ret = mmc_read((ptn + size - device_info_sz), (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002768 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002769 {
2770 dprintf(CRITICAL, "ERROR: Cannot read device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002771 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002772 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002773}
2774
tracychui9d60fc52020-06-05 17:31:38 +08002775#if defined(ENABLE_PRODINFO_ACCESS)
2776void write_prod_info_mmc(prod_info *dev)
2777{
2778 unsigned long long ptn = 0;
2779 unsigned long long size;
2780 int index = INVALID_PTN;
2781 uint32_t blocksize;
2782 uint8_t lun = 0;
2783 uint32_t ret = 0;
2784
2785 if (prodinfo_present)
2786 index = partition_get_index("prodinfo");
2787 else
2788 index = partition_get_index("aboot");
2789
2790 ptn = partition_get_offset(index);
2791 if(ptn == 0)
2792 {
2793 return;
2794 }
2795
2796 lun = partition_get_lun(index);
2797 mmc_set_lun(lun);
2798
2799 size = partition_get_size(index);
2800
2801 blocksize = mmc_get_device_blocksize();
2802
2803 if (prodinfo_present)
2804 ret = mmc_write(ptn, blocksize, (void *)prodinfo_buf);
2805 else
2806 ret = mmc_write((ptn + size - blocksize), blocksize, (void *)prodinfo_buf);
2807 if (ret)
2808 {
2809 dprintf(CRITICAL, "ERROR: Cannot write prod info\n");
2810 ASSERT(0);
2811 }
2812}
2813
2814void read_prod_info_mmc(struct prod_info *info)
2815{
2816 unsigned long long ptn = 0;
2817 unsigned long long size;
2818 int index = INVALID_PTN;
2819 uint32_t blocksize;
2820 uint32_t ret = 0;
2821
2822 if ((index = partition_get_index("prodinfo")) < 0)
2823 {
2824 prodinfo_present = false;
2825 index = partition_get_index("aboot");
2826 }
2827
2828 ptn = partition_get_offset(index);
2829 if(ptn == 0)
2830 {
2831 return;
2832 }
2833
2834 mmc_set_lun(partition_get_lun(index));
2835
2836 size = partition_get_size(index);
2837
2838 blocksize = mmc_get_device_blocksize();
2839
2840 if (prodinfo_present)
2841 ret = mmc_read(ptn, (void *)prodinfo_buf, blocksize);
2842 else
2843 ret = mmc_read((ptn + size - blocksize), (void *)prodinfo_buf, blocksize);
2844 if (ret)
2845 {
2846 dprintf(CRITICAL, "ERROR: Cannot read prod info\n");
2847 ASSERT(0);
2848 }
2849}
2850#endif
2851
Shashank Mittal162244e2011-08-08 19:01:25 -07002852void write_device_info_flash(device_info *dev)
2853{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002854 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002855 struct ptentry *ptn;
2856 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002857 if(info == NULL)
2858 {
2859 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2860 ASSERT(0);
2861 }
2862 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002863 ptable = flash_get_ptable();
2864 if (ptable == NULL)
2865 {
2866 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2867 return;
2868 }
2869
2870 ptn = ptable_find(ptable, "devinfo");
2871 if (ptn == NULL)
2872 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002873 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002874 return;
2875 }
2876
Mayank Groverdedbc892017-10-24 13:41:34 +05302877 memset(info, 0, BOOT_IMG_MAX_PAGE_SIZE);
Shashank Mittal162244e2011-08-08 19:01:25 -07002878 memcpy(info, dev, sizeof(device_info));
2879
2880 if (flash_write(ptn, 0, (void *)info_buf, page_size))
2881 {
2882 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2883 return;
2884 }
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002885 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002886}
2887
vijay kumarc65876c2015-04-24 13:29:16 +05302888static int read_allow_oem_unlock(device_info *dev)
2889{
vijay kumarc65876c2015-04-24 13:29:16 +05302890 unsigned offset;
2891 int index;
2892 unsigned long long ptn;
2893 unsigned long long ptn_size;
2894 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002895 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302896
vijay kumarca2e6812015-07-08 20:28:25 +05302897 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302898 if (index == INVALID_PTN)
2899 {
vijay kumarca2e6812015-07-08 20:28:25 +05302900 index = partition_get_index(frp_ptns[1]);
2901 if (index == INVALID_PTN)
2902 {
2903 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2904 return -1;
2905 }
vijay kumarc65876c2015-04-24 13:29:16 +05302906 }
2907
2908 ptn = partition_get_offset(index);
2909 ptn_size = partition_get_size(index);
2910 offset = ptn_size - blocksize;
2911
Mayank Grover48860402016-11-29 12:34:53 +05302912 /* Set Lun for partition */
2913 mmc_set_lun(partition_get_lun(index));
2914
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002915 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302916 {
2917 dprintf(CRITICAL, "Reading MMC failed\n");
2918 return -1;
2919 }
2920
2921 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2922 is_allow_unlock = buf[blocksize-1] & 0x01;
2923 return 0;
2924}
2925
2926static int write_allow_oem_unlock(bool allow_unlock)
2927{
vijay kumarc65876c2015-04-24 13:29:16 +05302928 unsigned offset;
vijay kumarc65876c2015-04-24 13:29:16 +05302929 int index;
2930 unsigned long long ptn;
2931 unsigned long long ptn_size;
2932 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002933 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302934
vijay kumarca2e6812015-07-08 20:28:25 +05302935 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302936 if (index == INVALID_PTN)
2937 {
vijay kumarca2e6812015-07-08 20:28:25 +05302938 index = partition_get_index(frp_ptns[1]);
2939 if (index == INVALID_PTN)
2940 {
2941 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2942 return -1;
2943 }
vijay kumarc65876c2015-04-24 13:29:16 +05302944 }
2945
2946 ptn = partition_get_offset(index);
2947 ptn_size = partition_get_size(index);
2948 offset = ptn_size - blocksize;
Mayank Grover48860402016-11-29 12:34:53 +05302949 mmc_set_lun(partition_get_lun(index));
vijay kumarc65876c2015-04-24 13:29:16 +05302950
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002951 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302952 {
2953 dprintf(CRITICAL, "Reading MMC failed\n");
2954 return -1;
2955 }
2956
2957 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2958 buf[blocksize-1] = allow_unlock;
2959 if (mmc_write(ptn + offset, blocksize, buf))
2960 {
2961 dprintf(CRITICAL, "Writing MMC failed\n");
2962 return -1;
2963 }
2964
2965 return 0;
2966}
2967
Shashank Mittal162244e2011-08-08 19:01:25 -07002968void read_device_info_flash(device_info *dev)
2969{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002970 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002971 struct ptentry *ptn;
2972 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002973 if(info == NULL)
2974 {
2975 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2976 ASSERT(0);
2977 }
2978 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002979 ptable = flash_get_ptable();
2980 if (ptable == NULL)
2981 {
2982 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2983 return;
2984 }
2985
2986 ptn = ptable_find(ptable, "devinfo");
2987 if (ptn == NULL)
2988 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002989 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002990 return;
2991 }
2992
2993 if (flash_read(ptn, 0, (void *)info_buf, page_size))
2994 {
2995 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2996 return;
2997 }
2998
2999 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
3000 {
Shashank Mittal162244e2011-08-08 19:01:25 -07003001 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
3002 info->is_unlocked = 0;
Shashank Mittala0032282011-08-26 14:50:11 -07003003 info->is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07003004 write_device_info_flash(info);
3005 }
3006 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003007 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07003008}
3009
3010void write_device_info(device_info *dev)
3011{
3012 if(target_is_emmc_boot())
3013 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003014 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
3015 if(info == NULL)
3016 {
3017 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
3018 ASSERT(0);
3019 }
3020 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003021 memcpy(info, dev, sizeof(struct device_info));
3022
3023#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05303024 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303025 is_secure_boot_enable()) {
3026 if((write_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
3027 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07003028 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07003029 else
3030 write_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003031#else
3032 write_device_info_mmc(info);
3033#endif
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003034 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07003035 }
3036 else
3037 {
3038 write_device_info_flash(dev);
3039 }
3040}
3041
Monika Singh94316462018-03-15 18:39:01 +05303042int read_rollback_index(uint32_t loc, uint64_t *roll_back_index)
3043{
3044 if (!devinfo_present) {
3045 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3046 return -EINVAL;
3047 }
3048 if (loc >= ARRAY_SIZE(device.rollback_index)) {
3049 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
3050 __func__, loc, ARRAY_SIZE(device.rollback_index));
3051 ASSERT(0);
3052 }
3053
3054 *roll_back_index = device.rollback_index[loc];
3055 return 0;
3056}
3057
3058int write_rollback_index(uint32_t loc, uint64_t roll_back_index)
3059{
3060 if (!devinfo_present) {
3061 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3062 return -EINVAL;
3063 }
3064 if (loc >= ARRAY_SIZE(device.rollback_index)) {
3065 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
3066 __func__, loc, ARRAY_SIZE(device.rollback_index));
3067 ASSERT(0);
3068 }
3069
3070 device.rollback_index[loc] = roll_back_index;
3071 write_device_info(&device);
3072 return 0;
3073}
3074
Monika Singhb0fad822018-03-15 18:50:55 +05303075int store_userkey(uint8_t *user_key, uint32_t user_key_size)
3076{
3077 if (!devinfo_present) {
3078 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3079 return -EINVAL;
3080 }
3081
3082 if (user_key_size > ARRAY_SIZE(device.user_public_key)) {
3083 dprintf(CRITICAL, "StoreUserKey, UserKeySize too large!\n");
3084 return -ENODEV;
3085 }
3086
3087 memcpy(device.user_public_key, user_key, user_key_size);
3088 device.user_public_key_length = user_key_size;
3089 write_device_info(&device);
3090 return 0;
3091}
3092
3093int erase_userkey()
3094{
3095 if (!devinfo_present) {
3096 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3097 return -EINVAL;
3098 }
3099 memset(device.user_public_key, 0, ARRAY_SIZE(device.user_public_key));
3100 device.user_public_key_length = 0;
3101 write_device_info(&device);
3102 return 0;
3103}
3104
3105int get_userkey(uint8_t **user_key, uint32_t *user_key_size)
3106{
3107 if (!devinfo_present) {
3108 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3109 return -EINVAL;
3110 }
3111 *user_key = device.user_public_key;
3112 *user_key_size = device.user_public_key_length;
3113 return 0;
3114}
3115
Shashank Mittal162244e2011-08-08 19:01:25 -07003116void read_device_info(device_info *dev)
3117{
3118 if(target_is_emmc_boot())
3119 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003120 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
3121 if(info == NULL)
3122 {
3123 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
3124 ASSERT(0);
3125 }
3126 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003127
3128#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05303129 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303130 is_secure_boot_enable()) {
3131 if((read_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
3132 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07003133 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07003134 else
3135 read_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003136#else
3137 read_device_info_mmc(info);
3138#endif
3139
3140 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
3141 {
3142 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
lijuang511a2b52015-08-14 20:50:51 +08003143 if (is_secure_boot_enable()) {
Channagoud Kadabi05f78ba2015-07-06 11:58:14 -07003144 info->is_unlocked = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05303145#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303146 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303147 info->is_unlock_critical = 0;
Parth Dixitddbc7352015-10-18 03:13:31 +05303148#endif
lijuang511a2b52015-08-14 20:50:51 +08003149 } else {
Channagoud Kadabi2fda4092015-07-07 13:34:11 -07003150 info->is_unlocked = 1;
Monika Singh292b3e92018-03-17 22:40:23 +05303151#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303152 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303153 info->is_unlock_critical = 1;
Parth Dixitddbc7352015-10-18 03:13:31 +05303154#endif
lijuang511a2b52015-08-14 20:50:51 +08003155 }
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003156 info->is_tampered = 0;
3157 info->charger_screen_enabled = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05303158#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303159 if (VB_M <= target_get_vb_version())
Monika Singh1c71a1c2019-12-03 12:12:48 +05303160 {
Mayank Grover889be1b2017-09-12 20:12:23 +05303161 info->verity_mode = 1; //enforcing by default
Monika Singh1c71a1c2019-12-03 12:12:48 +05303162 info->user_public_key_length = 0;
3163 memset(info->rollback_index, 0, sizeof(info->rollback_index));
3164 memset(info->user_public_key, 0, sizeof(info->user_public_key));
3165 }
Parth Dixitddbc7352015-10-18 03:13:31 +05303166#endif
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003167 write_device_info(info);
3168 }
jessicatseng8e7644c2020-04-22 11:13:20 +08003169
3170 info->charger_screen_enabled = 1;
3171 write_device_info(info);
3172
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003173 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003174 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07003175 }
3176 else
3177 {
3178 read_device_info_flash(dev);
3179 }
3180}
tracychui9d60fc52020-06-05 17:31:38 +08003181#if defined(ENABLE_PRODINFO_ACCESS)
3182void write_prod_info(prod_info *dev)
3183{
3184 if(target_is_emmc_boot())
3185 {
3186 struct prod_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
3187 if(info == NULL)
3188 {
3189 dprintf(CRITICAL, "Failed to allocate memory for prod info struct\n");
3190 ASSERT(0);
3191 }
3192 prodinfo_buf = info;
3193 memcpy(info, dev, sizeof(struct prod_info));
3194
3195 write_prod_info_mmc(info);
3196 free(info);
3197 }
3198}
3199
3200void read_prod_info(prod_info *dev)
3201{
3202 if(target_is_emmc_boot())
3203 {
3204 struct prod_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
3205 if(info == NULL)
3206 {
3207 dprintf(CRITICAL, "Failed to allocate memory for prod info struct\n");
3208 ASSERT(0);
3209 }
3210 prodinfo_buf = info;
3211
3212 read_prod_info_mmc(info);
3213
3214 if (memcmp(info->magic, PRODINFO_MAGIC, PRODINFO_MAGIC_SIZE))
3215 {
3216 memcpy(info->magic, PRODINFO_MAGIC, PRODINFO_MAGIC_SIZE);
3217 memcpy(info->isn, "No_Serial_Number", PRODINFO_MAX_ISN_LEN);
3218 memcpy(info->ssn, "No_Custer_Serial_Number", PRODINFO_MAX_SSN_LEN);
3219 info->is_adb_enabled = 0;
3220 write_prod_info(info);
3221 }
3222 memcpy(dev, info, sizeof(prod_info));
3223 free(info);
3224 }
3225}
3226#endif
Shashank Mittal162244e2011-08-08 19:01:25 -07003227
3228void reset_device_info()
3229{
3230 dprintf(ALWAYS, "reset_device_info called.");
Shashank Mittala0032282011-08-26 14:50:11 -07003231 device.is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07003232 write_device_info(&device);
3233}
3234
3235void set_device_root()
3236{
3237 dprintf(ALWAYS, "set_device_root called.");
Shashank Mittala0032282011-08-26 14:50:11 -07003238 device.is_tampered = 1;
Shashank Mittal162244e2011-08-08 19:01:25 -07003239 write_device_info(&device);
3240}
3241
lijuang4ece1e72015-08-14 21:02:36 +08003242/* set device unlock value
3243 * Must check FRP before call this function
3244 * Need to wipe data when unlock status changed
3245 * type 0: oem unlock
3246 * type 1: unlock critical
3247 * status 0: unlock as false
3248 * status 1: lock as true
3249 */
3250void set_device_unlock_value(int type, bool status)
lijuang21f12f52015-08-22 16:22:19 +08003251{
lijuang4ece1e72015-08-14 21:02:36 +08003252 if (type == UNLOCK)
3253 device.is_unlocked = status;
Monika Singh292b3e92018-03-17 22:40:23 +05303254#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303255 else if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303256 type == UNLOCK_CRITICAL)
3257 device.is_unlock_critical = status;
Parth Dixitddbc7352015-10-18 03:13:31 +05303258#endif
lijuang4ece1e72015-08-14 21:02:36 +08003259 write_device_info(&device);
3260}
3261
3262static void set_device_unlock(int type, bool status)
3263{
3264 int is_unlocked = -1;
3265 char response[MAX_RSP_SIZE];
3266
3267 /* check device unlock status if it is as expected */
3268 if (type == UNLOCK)
3269 is_unlocked = device.is_unlocked;
Monika Singh292b3e92018-03-17 22:40:23 +05303270#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303271 if(VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303272 type == UNLOCK_CRITICAL)
3273 {
3274 is_unlocked = device.is_unlock_critical;
3275 }
Parth Dixitddbc7352015-10-18 03:13:31 +05303276#endif
lijuang4ece1e72015-08-14 21:02:36 +08003277 if (is_unlocked == status) {
3278 snprintf(response, sizeof(response), "\tDevice already : %s", (status ? "unlocked!" : "locked!"));
3279 fastboot_info(response);
3280 fastboot_okay("");
3281 return;
3282 }
3283
3284 /* status is true, it means to unlock device */
lijuang07c5d6e2018-04-23 18:32:13 +08003285 if (status && !is_allow_unlock) {
3286 fastboot_fail("oem unlock is not allowed");
3287 return;
3288 }
lijuang21f12f52015-08-22 16:22:19 +08003289
ericlin4e397c42020-04-29 14:14:24 +08003290 if(target_build_variant_user()){
lijuang4ece1e72015-08-14 21:02:36 +08003291#if FBCON_DISPLAY_MSG
lijuang07c5d6e2018-04-23 18:32:13 +08003292 display_unlock_menu(type, status);
3293 fastboot_okay("");
3294 return;
lijuang4ece1e72015-08-14 21:02:36 +08003295#else
lijuang07c5d6e2018-04-23 18:32:13 +08003296 if (status && type == UNLOCK) {
3297 fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
3298 return;
lijuang21f12f52015-08-22 16:22:19 +08003299 }
lijuang07c5d6e2018-04-23 18:32:13 +08003300#endif
ericlin4e397c42020-04-29 14:14:24 +08003301 }
lijuang4ece1e72015-08-14 21:02:36 +08003302
3303 set_device_unlock_value(type, status);
3304
3305 /* wipe data */
3306 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05303307 memset(&msg, 0, sizeof(msg));
lijuang4ece1e72015-08-14 21:02:36 +08003308 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
3309 write_misc(0, &msg, sizeof(msg));
3310
3311 fastboot_okay("");
ericlin4e397c42020-04-29 14:14:24 +08003312 //reboot_device(RECOVERY_MODE);
lijuang21f12f52015-08-22 16:22:19 +08003313}
3314
lijuang511a2b52015-08-14 20:50:51 +08003315static bool critical_flash_allowed(const char * entry)
3316{
3317 uint32_t i = 0;
3318 if (entry == NULL)
3319 return false;
3320
3321 for (i = 0; i < ARRAY_SIZE(critical_flash_allowed_ptn); i++) {
3322 if(!strcmp(entry, critical_flash_allowed_ptn[i]))
3323 return true;
3324 }
3325 return false;
Matthew Qin271927e2015-03-31 22:07:07 -04003326}
3327
3328#if DEVICE_TREE
Amol Jadicb524072012-08-09 16:40:18 -07003329int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
3330{
3331 uint32 dt_image_offset = 0;
Amol Jadicb524072012-08-09 16:40:18 -07003332 uint32_t n;
Monika Singh292b3e92018-03-17 22:40:23 +05303333 struct dt_table *table = NULL;
Amol Jadicb524072012-08-09 16:40:18 -07003334 struct dt_entry dt_entry;
Monika Singh292b3e92018-03-17 22:40:23 +05303335 uint32_t dt_hdr_size = 0;
Amol Jadicb524072012-08-09 16:40:18 -07003336 unsigned int compressed_size = 0;
3337 unsigned int dtb_size = 0;
3338 unsigned int out_avai_len = 0;
3339 unsigned char *out_addr = NULL;
3340 unsigned char *best_match_dt_addr = NULL;
3341 int rc;
3342
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303343 boot_img_hdr *hdr = (boot_img_hdr *) (boot_image_start);
Amol Jadicb524072012-08-09 16:40:18 -07003344
Parth Dixit4097b622016-03-15 14:42:27 +05303345#ifndef OSVERSION_IN_BOOTIMAGE
3346 dt_size = hdr->dt_size;
3347#endif
3348
3349 if(dt_size != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07003350 /* add kernel offset */
3351 dt_image_offset += page_size;
3352 n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
3353 dt_image_offset += n;
3354
3355 /* add ramdisk offset */
3356 n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
3357 dt_image_offset += n;
3358
3359 /* add second offset */
3360 if(hdr->second_size != 0) {
3361 n = ROUND_TO_PAGE(hdr->second_size, page_mask);
3362 dt_image_offset += n;
3363 }
3364
3365 /* offset now point to start of dt.img */
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07003366 table = (struct dt_table*)(boot_image_start + dt_image_offset);
Amol Jadicb524072012-08-09 16:40:18 -07003367
Deepa Dinamani19648b42013-09-05 17:05:55 -07003368 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07003369 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
3370 return -1;
3371 }
P.V. Phani Kumar82916762016-03-09 09:20:19 +05303372
3373 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
3374 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05303375 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05303376 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
3377 return -1;
3378 }
3379
Joel Kingaa335dc2013-06-03 16:11:08 -07003380 /* Find index of device tree within device tree table */
3381 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Amol Jadicb524072012-08-09 16:40:18 -07003382 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
3383 return -1;
3384 }
3385
Matthew Qin271927e2015-03-31 22:07:07 -04003386 best_match_dt_addr = (unsigned char *)boot_image_start + dt_image_offset + dt_entry.offset;
3387 if (is_gzip_package(best_match_dt_addr, dt_entry.size))
3388 {
3389 out_addr = (unsigned char *)target_get_scratch_address() + scratch_offset;
3390 out_avai_len = target_get_max_flash_size() - scratch_offset;
Matthew Qin0b15b322015-05-19 05:20:54 -04003391 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003392 rc = decompress(best_match_dt_addr,
3393 dt_entry.size, out_addr, out_avai_len,
3394 &compressed_size, &dtb_size);
3395 if (rc)
3396 {
Matthew Qin0b15b322015-05-19 05:20:54 -04003397 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003398 ASSERT(0);
3399 }
3400
Matthew Qin0b15b322015-05-19 05:20:54 -04003401 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003402 best_match_dt_addr = out_addr;
3403 } else {
3404 dtb_size = dt_entry.size;
3405 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003406 /* Validate and Read device device tree in the "tags_add */
Mayank Grovere559cec2017-10-17 15:12:03 +05303407 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
3408 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003409 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303410 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003411 return -1;
3412 }
3413
Amol Jadicb524072012-08-09 16:40:18 -07003414 /* Read device device tree in the "tags_add */
Matthew Qin271927e2015-03-31 22:07:07 -04003415 memmove((void*) hdr->tags_addr, (void *)best_match_dt_addr, dtb_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003416 } else
3417 return -1;
Amol Jadicb524072012-08-09 16:40:18 -07003418
3419 /* Everything looks fine. Return success. */
3420 return 0;
3421}
3422#endif
3423
Brian Swetland9c4c0752009-01-25 16:23:50 -08003424void cmd_boot(const char *arg, void *data, unsigned sz)
3425{
3426 unsigned kernel_actual;
3427 unsigned ramdisk_actual;
Kishor PKd8ddcad2017-07-27 13:53:57 +05303428 unsigned second_actual;
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003429 uint32_t image_actual;
3430 uint32_t dt_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303431 boot_img_hdr *hdr = NULL;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003432 struct kernel64_hdr *kptr = NULL;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003433 char *ptr = ((char*) data);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003434 int ret = 0;
3435 uint8_t dtb_copied = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003436 unsigned int out_len = 0;
3437 unsigned int out_avai_len = 0;
3438 unsigned char *out_addr = NULL;
3439 uint32_t dtb_offset = 0;
3440 unsigned char *kernel_start_addr = NULL;
3441 unsigned int kernel_size = 0;
Matthew Qin271927e2015-03-31 22:07:07 -04003442 unsigned int scratch_offset = 0;
Saranya Chidurab4933332018-10-15 17:30:06 +05303443#if VERIFIED_BOOT_2
3444 void *dtbo_image_buf = NULL;
3445 uint32_t dtbo_image_sz = 0;
3446 void *vbmeta_image_buf = NULL;
3447 uint32_t vbmeta_image_sz = 0;
3448#endif
Monika Singh292b3e92018-03-17 22:40:23 +05303449#if !VERIFIED_BOOT_2
3450 uint32_t sig_actual = 0;
3451 uint32_t sig_size = 0;
3452#ifdef MDTP_SUPPORT
3453 static bool is_mdtp_activated = 0;
3454#endif /* MDTP_SUPPORT */
3455#endif
Matthew Qinbb7923d2015-02-09 10:56:09 +08003456
lijuang2008ff22016-03-07 17:56:27 +08003457#if FBCON_DISPLAY_MSG
3458 /* Exit keys' detection thread firstly */
3459 exit_menu_keys_detection();
3460#endif
3461
Monika Singh292b3e92018-03-17 22:40:23 +05303462#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi6d5375e2015-06-23 17:15:42 -07003463 if(target_build_variant_user() && !device.is_unlocked)
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003464 {
3465 fastboot_fail("unlock device to use this command");
lijuang2008ff22016-03-07 17:56:27 +08003466 goto boot_failed;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003467 }
3468#endif
3469
Brian Swetland9c4c0752009-01-25 16:23:50 -08003470 if (sz < sizeof(hdr)) {
3471 fastboot_fail("invalid bootimage header");
lijuang2008ff22016-03-07 17:56:27 +08003472 goto boot_failed;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003473 }
3474
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303475 hdr = (boot_img_hdr *)data;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003476
3477 /* ensure commandline is terminated */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003478 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003479
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003480 if(target_is_emmc_boot() && hdr->page_size) {
3481 page_size = hdr->page_size;
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07003482 page_mask = page_size - 1;
3483 }
3484
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003485 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
3486 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303487 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003488#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05303489#ifndef OSVERSION_IN_BOOTIMAGE
3490 dt_size = hdr->dt_size;
3491#endif
3492 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003493#endif
3494
3495 image_actual = ADD_OF(page_size, kernel_actual);
3496 image_actual = ADD_OF(image_actual, ramdisk_actual);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303497 image_actual = ADD_OF(image_actual, second_actual);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003498 image_actual = ADD_OF(image_actual, dt_actual);
3499
Kishor PK5134b332017-05-09 17:50:08 +05303500 /* Checking to prevent oob access in read_der_message_length */
3501 if (image_actual > sz) {
3502 fastboot_fail("bootimage header fields are invalid");
3503 goto boot_failed;
3504 }
Saranya Chidurab4933332018-10-15 17:30:06 +05303505
Monika Singh292b3e92018-03-17 22:40:23 +05303506#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05303507 /* Pass size of boot partition, as imgsize, to avoid
3508 read fewer bytes error */
3509 image_actual = partition_get_size(partition_get_index("boot"));
Saranya Chidurab4933332018-10-15 17:30:06 +05303510
3511 /* load and validate dtbo partition */
3512 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
3513
3514 /* load vbmeta partition */
3515 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
3516
Monika Singh292b3e92018-03-17 22:40:23 +05303517 memset(&info, 0, sizeof(bootinfo));
Saranya Chidurab4933332018-10-15 17:30:06 +05303518
3519 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(data);
3520 info.images[IMG_BOOT].imgsize = image_actual;
3521 info.images[IMG_BOOT].name = "boot";
3522 ++info.num_loaded_images;
3523
3524 /* Pass loaded dtbo image */
3525 if (dtbo_image_buf != NULL) {
3526 info.images[IMG_DTBO].image_buffer = SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
3527 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
3528 info.images[IMG_DTBO].name = "dtbo";
3529 ++info.num_loaded_images;
3530 }
3531
3532 /* Pass loaded vbmeta image */
3533 if (vbmeta_image_buf != NULL) {
3534 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
3535 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
3536 info.images[IMG_VBMETA].name = "vbmeta";
3537 ++info.num_loaded_images;
3538 }
3539
Monika Singh292b3e92018-03-17 22:40:23 +05303540 info.multi_slot_boot = partition_multislot_is_supported();
3541 if (load_image_and_auth(&info))
3542 goto boot_failed;
3543 vbcmdline = info.vbcmdline;
Saranya Chidurab4933332018-10-15 17:30:06 +05303544
3545 /* Free the buffer allocated to vbmeta post verification */
3546 if (vbmeta_image_buf != NULL) {
3547 free(vbmeta_image_buf);
3548 --info.num_loaded_images;
3549 }
Monika Singh292b3e92018-03-17 22:40:23 +05303550#else
Kishor PK5134b332017-05-09 17:50:08 +05303551 sig_size = sz - image_actual;
3552
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303553 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Monika Singh292b3e92018-03-17 22:40:23 +05303554 unsigned chk;
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303555 /* Calculate the signature length from boot image */
3556 sig_actual = read_der_message_length(
Kishor PK5134b332017-05-09 17:50:08 +05303557 (unsigned char*)(data + image_actual), sig_size);
Monika Singh292b3e92018-03-17 22:40:23 +05303558 chk = ADD_OF(image_actual, sig_actual);
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003559
Monika Singh292b3e92018-03-17 22:40:23 +05303560 if (chk > sz) {
Kishor PK5134b332017-05-09 17:50:08 +05303561 fastboot_fail("bootimage header fields are invalid");
3562 goto boot_failed;
3563 }
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003564 }
3565
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003566 // Initialize boot state before trying to verify boot.img
3567#if VERIFIED_BOOT
Channagoud Kadabi699466e2015-11-03 12:37:42 -08003568 boot_verifier_init();
Mayank Groverb337e932017-01-18 20:00:40 +05303569#endif
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003570 /* Handle overflow if the input image size is greater than
3571 * boot image buffer can hold
3572 */
Monika Singh292b3e92018-03-17 22:40:23 +05303573 if ((target_get_max_flash_size() - page_size) < image_actual)
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003574 {
3575 fastboot_fail("booimage: size is greater than boot image buffer can hold");
lijuang2008ff22016-03-07 17:56:27 +08003576 goto boot_failed;
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003577 }
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003578
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003579 /* Verify the boot image
3580 * device & page_size are initialized in aboot_init
3581 */
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003582 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003583 /* Pass size excluding signature size, otherwise we would try to
3584 * access signature beyond its length
3585 */
Monika Singh292b3e92018-03-17 22:40:23 +05303586 verify_signed_bootimg((uint32_t)data, image_actual);
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003587 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003588#ifdef MDTP_SUPPORT
3589 else
3590 {
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003591 /* fastboot boot is not allowed when MDTP is activated */
Amit Blay4aa292f2015-04-28 21:55:59 +03003592 mdtp_ext_partition_verification_t ext_partition;
Amit Blay8a510302015-08-17 09:20:01 +03003593
3594 if (!is_mdtp_activated) {
3595 ext_partition.partition = MDTP_PARTITION_NONE;
3596 mdtp_fwlock_verify_lock(&ext_partition);
3597 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003598 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003599
Amir Kotzer7c768c02016-04-13 09:08:05 +03003600 /* If mdtp state cannot be validate, block fastboot boot*/
3601 if(mdtp_activated(&is_mdtp_activated)){
3602 dprintf(CRITICAL, "mdtp_activated cannot validate state.\n");
3603 dprintf(CRITICAL, "Can not proceed with fastboot boot command.\n");
3604 goto boot_failed;
3605 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003606 if(is_mdtp_activated){
3607 dprintf(CRITICAL, "fastboot boot command is not available.\n");
lijuang2008ff22016-03-07 17:56:27 +08003608 goto boot_failed;
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003609 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003610#endif /* MDTP_SUPPORT */
Monika Singh292b3e92018-03-17 22:40:23 +05303611#endif /* VERIFIED_BOOT_2 else */
Amit Blay4aa292f2015-04-28 21:55:59 +03003612
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003613#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05303614 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303615 {
3616 /* set boot and system versions. */
3617 set_os_version((unsigned char *)data);
3618 // send root of trust
3619 if(!send_rot_command((uint32_t)device.is_unlocked))
3620 ASSERT(0);
3621 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05303622#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003623 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08003624 * Check if the kernel image is a gzip package. If yes, need to decompress it.
3625 * If not, continue booting.
3626 */
3627 if (is_gzip_package((unsigned char *)(data + page_size), hdr->kernel_size))
3628 {
3629 out_addr = (unsigned char *)target_get_scratch_address();
3630 out_addr = (unsigned char *)(out_addr + image_actual + page_size);
3631 out_avai_len = target_get_max_flash_size() - image_actual - page_size;
Saranya Chidurab4933332018-10-15 17:30:06 +05303632#if VERIFIED_BOOT_2
3633 if (dtbo_image_sz)
3634 out_avai_len -= DTBO_IMG_BUF;
3635#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04003636 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003637 ret = decompress((unsigned char *)(ptr + page_size),
3638 hdr->kernel_size, out_addr, out_avai_len,
3639 &dtb_offset, &out_len);
3640 if (ret)
3641 {
Matthew Qin0b15b322015-05-19 05:20:54 -04003642 dprintf(CRITICAL, "decompressing image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003643 ASSERT(0);
3644 }
3645
Matthew Qin0b15b322015-05-19 05:20:54 -04003646 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003647 kptr = (struct kernel64_hdr *)out_addr;
3648 kernel_start_addr = out_addr;
3649 kernel_size = out_len;
3650 } else {
3651 kptr = (struct kernel64_hdr*)((char *)data + page_size);
3652 kernel_start_addr = (unsigned char *)((char *)data + page_size);
3653 kernel_size = hdr->kernel_size;
3654 }
3655
3656 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003657 * Update the kernel/ramdisk/tags address if the boot image header
3658 * has default values, these default values come from mkbootimg when
3659 * the boot image is flashed using fastboot flash:raw
3660 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08003661 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Dima Zavin3cadfff2013-03-21 14:30:48 -07003662
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003663 /* Get virtual addresses since the hdr saves physical addresses. */
3664 hdr->kernel_addr = VA(hdr->kernel_addr);
3665 hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
3666 hdr->tags_addr = VA(hdr->tags_addr);
Brian Swetland9c4c0752009-01-25 16:23:50 -08003667
Matthew Qinbb7923d2015-02-09 10:56:09 +08003668 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003669 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08003670 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05303671 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
3672 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
3673 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003674 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303675 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003676 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003677 }
3678
Amol Jadicb524072012-08-09 16:40:18 -07003679#if DEVICE_TREE
Matthew Qin271927e2015-03-31 22:07:07 -04003680 scratch_offset = image_actual + page_size + out_len;
Amol Jadicb524072012-08-09 16:40:18 -07003681 /* find correct dtb and copy it to right location */
Matthew Qin271927e2015-03-31 22:07:07 -04003682 ret = copy_dtb(data, scratch_offset);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003683
3684 dtb_copied = !ret ? 1 : 0;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003685#else
Mayank Grovere559cec2017-10-17 15:12:03 +05303686 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
3687 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003688 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303689 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003690 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003691 }
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003692#endif
3693
3694 /* Load ramdisk & kernel */
3695 memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
Matthew Qinbb7923d2015-02-09 10:56:09 +08003696 memmove((void*) hdr->kernel_addr, (char*) (kernel_start_addr), kernel_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003697
3698#if DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05303699 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
3700 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Matthew Qinbb7923d2015-02-09 10:56:09 +08003701 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303702 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003703 goto boot_failed;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003704 }
3705
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003706 /*
3707 * If dtb is not found look for appended DTB in the kernel.
3708 * If appended dev tree is found, update the atags with
3709 * memory address to the DTB appended location on RAM.
3710 * Else update with the atags address in the kernel header
3711 */
3712 if (!dtb_copied) {
3713 void *dtb;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003714 dtb = dev_tree_appended((void*)(ptr + page_size),
3715 hdr->kernel_size, dtb_offset,
Dima Zavine63e5572013-05-03 12:23:06 -07003716 (void *)hdr->tags_addr);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003717 if (!dtb) {
3718 fastboot_fail("dtb not found");
lijuang2008ff22016-03-07 17:56:27 +08003719 goto boot_failed;
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003720 }
Amol Jadicb524072012-08-09 16:40:18 -07003721 }
3722#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08003723
3724 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07003725 fastboot_stop();
Brian Swetland9c4c0752009-01-25 16:23:50 -08003726
Dima Zavin77e41f32013-03-06 16:10:43 -08003727 boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003728 (const char*) hdr->cmdline, board_machtype(),
3729 (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
lijuang2008ff22016-03-07 17:56:27 +08003730
3731 /* fastboot already stop, it's no need to show fastboot menu */
3732 return;
3733boot_failed:
3734#if FBCON_DISPLAY_MSG
3735 /* revert to fastboot menu if boot failed */
3736 display_fastboot_menu();
3737#endif
3738 return;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003739}
3740
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003741void cmd_erase_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08003742{
3743 struct ptentry *ptn;
3744 struct ptable *ptable;
3745
3746 ptable = flash_get_ptable();
3747 if (ptable == NULL) {
3748 fastboot_fail("partition table doesn't exist");
3749 return;
3750 }
3751
3752 ptn = ptable_find(ptable, arg);
3753 if (ptn == NULL) {
3754 fastboot_fail("unknown partition name");
3755 return;
3756 }
3757
Monika Singh292b3e92018-03-17 22:40:23 +05303758 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3759 dprintf(INFO, "erasing avb_custom_key\n");
3760 if (erase_userkey()) {
3761 fastboot_fail("Erasing avb_custom_key failed");
3762 } else {
3763 fastboot_okay("");
3764 }
3765 return;
3766 }
3767
Dima Zavin214cc642009-01-26 11:16:21 -08003768 if (flash_erase(ptn)) {
3769 fastboot_fail("failed to erase partition");
3770 return;
3771 }
3772 fastboot_okay("");
3773}
3774
Bikas Gurungd48bd242010-09-04 19:54:32 -07003775
3776void cmd_erase_mmc(const char *arg, void *data, unsigned sz)
3777{
3778 unsigned long long ptn = 0;
Oliver Wangcee448d2013-10-22 18:40:13 +08003779 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003780 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003781 uint8_t lun = 0;
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303782 char *footer = NULL;
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05303783 char EraseResultStr[MAX_RSP_SIZE] = "";
3784 VirtualAbMergeStatus SnapshotMergeStatus;
Bikas Gurungd48bd242010-09-04 19:54:32 -07003785
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003786#if VERIFIED_BOOT
3787 if(!strcmp(arg, KEYSTORE_PTN_NAME))
3788 {
3789 if(!device.is_unlocked)
3790 {
3791 fastboot_fail("unlock device to erase keystore");
3792 return;
3793 }
3794 }
3795#endif
3796
Kinson Chikf1a43512011-07-14 11:28:39 -07003797 index = partition_get_index(arg);
3798 ptn = partition_get_offset(index);
Oliver Wangcee448d2013-10-22 18:40:13 +08003799 size = partition_get_size(index);
Neeti Desaica8c9602011-10-06 11:40:00 -07003800
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05303801 if (target_virtual_ab_supported()) {
3802 if (CheckVirtualAbCriticalPartition (arg)) {
3803 snprintf(EraseResultStr, MAX_RSP_SIZE,"Erase of %s is not allowed in %s state",
3804 arg, SnapshotMergeState);
3805 fastboot_fail(EraseResultStr);
3806 return;
3807 }
3808 SnapshotMergeStatus = GetSnapshotMergeStatus ();
3809 if (((SnapshotMergeStatus == MERGING) || (SnapshotMergeStatus == SNAPSHOTTED)) &&
3810 !strncmp (arg, "super", strlen ("super"))) {
3811
3812 if(SetSnapshotMergeStatus (CANCELLED))
3813 {
3814 fastboot_fail("Failed to update snapshot state to cancel");
3815 return;
3816 }
3817
3818 //updating fbvar snapshot-merge-state
3819 snprintf(SnapshotMergeState,strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
3820 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
3821 }
3822 }
3823
Monika Singhc4778b72018-05-16 11:16:42 +05303824 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3825 dprintf(INFO, "erasing avb_custom_key\n");
3826 if (erase_userkey()) {
3827 fastboot_fail("Erasing avb_custom_key failed");
3828 } else {
3829 fastboot_okay("");
3830 }
3831 return;
3832 }
3833
Kinson Chikf1a43512011-07-14 11:28:39 -07003834 if(ptn == 0) {
Neeti Desaica8c9602011-10-06 11:40:00 -07003835 fastboot_fail("Partition table doesn't exist\n");
Bikas Gurungd48bd242010-09-04 19:54:32 -07003836 return;
3837 }
Kun Liang2f1601a2013-08-12 16:29:54 +08003838
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003839 lun = partition_get_lun(index);
3840 mmc_set_lun(lun);
3841
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003842 if (platform_boot_dev_isemmc())
3843 {
3844 if (mmc_erase_card(ptn, size)) {
3845 fastboot_fail("failed to erase partition\n");
3846 return;
3847 }
3848 } else {
3849 BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE);
3850 size = partition_get_size(index);
3851 if (size > DEFAULT_ERASE_SIZE)
3852 size = DEFAULT_ERASE_SIZE;
Kun Liang2f1601a2013-08-12 16:29:54 +08003853
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003854 /* Simple inefficient version of erase. Just writing
3855 0 in first several blocks */
3856 if (mmc_write(ptn , size, (unsigned int *)out)) {
3857 fastboot_fail("failed to erase partition");
3858 return;
3859 }
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303860 /*Erase FDE metadata at the userdata footer*/
3861 if(!(strncmp(arg, "userdata", 8)))
3862 {
3863 footer = memalign(CACHE_LINE, FOOTER_SIZE);
3864 memset((void *)footer, 0, FOOTER_SIZE);
3865
3866 size = partition_get_size(index);
3867
3868 if (mmc_write((ptn + size) - FOOTER_SIZE , FOOTER_SIZE, (unsigned int *)footer)) {
3869 fastboot_fail("failed to erase userdata footer");
3870 free(footer);
3871 return;
3872 }
3873 free(footer);
3874 }
Bikas Gurungd48bd242010-09-04 19:54:32 -07003875 }
Monika Singh292b3e92018-03-17 22:40:23 +05303876#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303877 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303878 !(strncmp(arg, "userdata", 8)) &&
3879 send_delete_keys_to_tz())
Sridhar Parasuram32b30662015-07-10 13:33:22 -07003880 ASSERT(0);
3881#endif
Bikas Gurungd48bd242010-09-04 19:54:32 -07003882 fastboot_okay("");
3883}
3884
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003885void cmd_erase(const char *arg, void *data, unsigned sz)
3886{
Monika Singh292b3e92018-03-17 22:40:23 +05303887#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07003888 if (target_build_variant_user())
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003889 {
Sridhar Parasuramc32d07d2015-07-12 10:57:48 -07003890 if(!device.is_unlocked)
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003891 {
Channagoud Kadabi35297672015-06-13 11:09:49 -07003892 fastboot_fail("device is locked. Cannot erase");
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003893 return;
3894 }
3895 }
3896#endif
3897
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003898 if(target_is_emmc_boot())
3899 cmd_erase_mmc(arg, data, sz);
3900 else
3901 cmd_erase_nand(arg, data, sz);
3902}
Bikas Gurungd48bd242010-09-04 19:54:32 -07003903
Mayank Grover11ff9692018-01-11 11:54:49 +05303904/* Get the size from partiton name */
3905static void get_partition_size(const char *arg, char *response)
3906{
3907 uint64_t ptn = 0;
3908 uint64_t size;
3909 int index = INVALID_PTN;
3910
3911 index = partition_get_index(arg);
3912
3913 if (index == INVALID_PTN)
3914 {
3915 dprintf(CRITICAL, "Invalid partition index\n");
3916 return;
3917 }
3918
3919 ptn = partition_get_offset(index);
3920
3921 if(!ptn)
3922 {
3923 dprintf(CRITICAL, "Invalid partition name %s\n", arg);
3924 return;
3925 }
3926
3927 size = partition_get_size(index);
3928
3929 snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size);
3930 return;
3931}
3932
Mayank Grover52cd10a2018-03-15 12:57:54 +05303933/* Function to check partition type of a partition*/
3934static fs_signature_type
3935check_partition_fs_signature(const char *arg)
3936{
3937 fs_signature_type ret = NO_FS;
3938 int index;
3939 unsigned long long ptn;
Mayank Grover399826a2018-08-27 12:15:15 +05303940 char *buffer = memalign(CACHE_LINE, mmc_blocksize);
3941 uint32_t sb_blk_offset = 0;
3942 char *sb_buffer = buffer;
3943
Mayank Grover52cd10a2018-03-15 12:57:54 +05303944 if (!sb_buffer)
3945 {
3946 dprintf(CRITICAL, "ERROR: Failed to allocate buffer for superblock\n");
3947 goto out;
3948 }
3949
3950 /* Read super block */
3951 if ((index = partition_get_index(arg)) < 0)
3952 {
3953 dprintf(CRITICAL, "ERROR: %s() doesn't exsit\n", arg);
3954 goto out;
3955 }
3956 ptn = partition_get_offset(index);
3957 mmc_set_lun(partition_get_lun(index));
Mayank Grover399826a2018-08-27 12:15:15 +05303958 sb_blk_offset = (FS_SUPERBLOCK_OFFSET/mmc_blocksize);
3959
3960 if(mmc_read(ptn + (sb_blk_offset * mmc_blocksize),
Mayank Grover52cd10a2018-03-15 12:57:54 +05303961 (void *)sb_buffer, mmc_blocksize))
3962 {
3963 dprintf(CRITICAL, "ERROR: Failed to read Superblock\n");
3964 goto out;
3965 }
3966
Mayank Grover399826a2018-08-27 12:15:15 +05303967 if (sb_blk_offset == 0)
3968 sb_buffer += FS_SUPERBLOCK_OFFSET;
3969
3970 if (*((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])) == (uint16)EXT_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05303971 {
3972 dprintf(SPEW, "%s() Found EXT FS\n", arg);
3973 ret = EXT_FS_SIGNATURE;
3974 }
Mayank Grover399826a2018-08-27 12:15:15 +05303975 else if (*((uint32 *)(&sb_buffer[F2FS_MAGIC_OFFSET_SB])) == F2FS_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05303976 {
3977 dprintf(SPEW, "%s() Found F2FS FS\n", arg);
3978 ret = EXT_F2FS_SIGNATURE;
3979 }
3980 else
3981 {
3982 dprintf(SPEW, "%s() Reverting to default 0x%x\n",
3983 arg, *((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])));
3984 ret = NO_FS;
3985 }
3986
3987out:
Mayank Grover399826a2018-08-27 12:15:15 +05303988 if(buffer)
3989 free(buffer);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303990 return ret;
3991}
3992
Mayank Groverd38fe012018-03-13 15:33:16 +05303993/* Function to get partition type */
3994static void get_partition_type(const char *arg, char *response)
3995{
3996 uint n = 0;
Mayank Grover52cd10a2018-03-15 12:57:54 +05303997 fs_signature_type fs_signature;
Mayank Groverd38fe012018-03-13 15:33:16 +05303998
3999 if (arg == NULL ||
4000 response == NULL)
4001 {
4002 dprintf(CRITICAL, "Invalid input parameter\n");
4003 return;
4004 }
4005
4006 /* By default copy raw to response */
Mayank Grover0e559042018-04-11 17:49:30 +05304007 strlcpy(response, RAW_STR, MAX_RSP_SIZE);
Mayank Groverd38fe012018-03-13 15:33:16 +05304008
4009 /* Mark partiton type for known paritions only */
4010 for (n=0; n < ARRAY_SIZE(part_type_known); n++)
4011 {
4012 if (!strncmp(part_type_known[n].part_name, arg, strlen(arg)))
4013 {
Mayank Grover52cd10a2018-03-15 12:57:54 +05304014 /* Check partition for FS signature */
4015 fs_signature = check_partition_fs_signature(arg);
4016 switch (fs_signature)
4017 {
4018 case EXT_FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05304019 strlcpy(response, EXT_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05304020 break;
4021 case EXT_F2FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05304022 strlcpy(response, F2FS_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05304023 break;
4024 case NO_FS:
Mayank Grover0e559042018-04-11 17:49:30 +05304025 strlcpy(response, part_type_known[n].type_response, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05304026 }
Mayank Groverd38fe012018-03-13 15:33:16 +05304027 }
4028 }
4029 return;
4030}
4031
Mayank Grover11ff9692018-01-11 11:54:49 +05304032/*
4033 * Publish the partition type & size info
4034 * fastboot getvar will publish the required information.
4035 * fastboot getvar partition_size:<partition_name>: partition size in hex
4036 * fastboot getvar partition_type:<partition_name>: partition type (ext/fat)
4037 */
4038static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
4039{
Mayank Groverd38fe012018-03-13 15:33:16 +05304040 uint8_t i;
Mayank Grover11ff9692018-01-11 11:54:49 +05304041 static bool published = false;
4042 struct partition_entry *ptn_entry =
4043 partition_get_partition_entries();
4044 memset(info, 0, sizeof(struct getvar_partition_info)* num_parts);
4045
4046 for (i = 0; i < num_parts; i++) {
4047 strlcat(info[i].part_name, (const char *)ptn_entry[i].name, MAX_RSP_SIZE);
4048 strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
4049 strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
4050
Mayank Groverd38fe012018-03-13 15:33:16 +05304051 get_partition_type(info[i].part_name, info[i].type_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05304052 get_partition_size(info[i].part_name, info[i].size_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05304053 if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
4054 {
4055 dprintf(CRITICAL, "partition size name truncated\n");
4056 return;
4057 }
4058 if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
4059 {
4060 dprintf(CRITICAL, "partition type name truncated\n");
4061 return;
4062 }
4063
4064 if (!published)
4065 {
4066 /* publish partition size & type info */
4067 fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response);
4068 fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response);
4069 }
4070 }
4071 if (!published)
4072 published = true;
4073}
4074
4075
Ajay Dudani5c761132011-04-07 20:19:04 -07004076void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
Shashank Mittal23b8f422010-04-16 19:27:21 -07004077{
4078 unsigned long long ptn = 0;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07004079 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07004080 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004081 char *token = NULL;
4082 char *pname = NULL;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07004083 char *sp;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004084 uint8_t lun = 0;
4085 bool lun_set = false;
Mayank Grover351a75e2017-05-30 20:06:08 +05304086 int current_active_slot = INVALID;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07004087
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07004088 token = strtok_r((char *)arg, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004089 pname = token;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07004090 token = strtok_r(NULL, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004091 if(token)
4092 {
4093 lun = atoi(token);
4094 mmc_set_lun(lun);
4095 lun_set = true;
4096 }
4097
Mao Jinlong226f33a2014-07-04 17:24:10 +08004098 if (pname)
Greg Grisco6e754772011-06-23 12:19:39 -07004099 {
Channagoud Kadabiad259832015-05-29 11:14:17 -07004100 if (!strncmp(pname, "frp-unlock", strlen("frp-unlock")))
4101 {
4102 if (!aboot_frp_unlock(pname, data, sz))
4103 {
4104 fastboot_info("FRP unlock successful");
4105 fastboot_okay("");
4106 }
4107 else
4108 fastboot_fail("Secret key is invalid, please update the bootloader with secret key");
4109
4110 return;
4111 }
4112
Mao Jinlong226f33a2014-07-04 17:24:10 +08004113 if (!strcmp(pname, "partition"))
4114 {
4115 dprintf(INFO, "Attempt to write partition image.\n");
4116 if (write_partition(sz, (unsigned char *) data)) {
4117 fastboot_fail("failed to write partition");
Greg Grisco6e754772011-06-23 12:19:39 -07004118 return;
4119 }
Mayank Grover11ff9692018-01-11 11:54:49 +05304120 /* Re-publish partition table */
4121 publish_getvar_partition_info(part_info, partition_get_partition_count());
Mayank Grover351a75e2017-05-30 20:06:08 +05304122
4123 /* Rescan partition table to ensure we have multislot support*/
4124 if (partition_scan_for_multislot())
4125 {
4126 current_active_slot = partition_find_active_slot();
4127 dprintf(INFO, "Multislot supported: Slot %s active",
4128 (SUFFIX_SLOT(current_active_slot)));
4129 }
4130 partition_mark_active_slot(current_active_slot);
Greg Grisco6e754772011-06-23 12:19:39 -07004131 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08004132 else
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004133 {
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004134#if VERIFIED_BOOT
4135 if(!strcmp(pname, KEYSTORE_PTN_NAME))
4136 {
4137 if(!device.is_unlocked)
4138 {
4139 fastboot_fail("unlock device to flash keystore");
4140 return;
4141 }
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +05304142 if(!boot_verify_validate_keystore((unsigned char *)data,sz))
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004143 {
4144 fastboot_fail("image is not a keystore file");
4145 return;
4146 }
4147 }
4148#endif
Mao Jinlong226f33a2014-07-04 17:24:10 +08004149 index = partition_get_index(pname);
4150 ptn = partition_get_offset(index);
4151 if(ptn == 0) {
4152 fastboot_fail("partition table doesn't exist");
4153 return;
4154 }
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004155
Mayank Grover351a75e2017-05-30 20:06:08 +05304156 if (!strncmp(pname, "boot", strlen("boot"))
4157 || !strcmp(pname, "recovery"))
4158 {
Ashish Bhimanpalliwar84f7db92020-09-23 11:59:16 +05304159 if ((sz < BOOT_MAGIC_SIZE) || memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Mao Jinlong226f33a2014-07-04 17:24:10 +08004160 fastboot_fail("image is not a boot image");
4161 return;
4162 }
Mayank Grover351a75e2017-05-30 20:06:08 +05304163
4164 /* Reset multislot_partition attributes in case of flashing boot */
4165 if (partition_multislot_is_supported())
4166 {
4167 partition_reset_attributes(index);
4168 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08004169 }
4170
4171 if(!lun_set)
4172 {
4173 lun = partition_get_lun(index);
4174 mmc_set_lun(lun);
4175 }
4176
4177 size = partition_get_size(index);
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05304178 if (ROUND_TO_PAGE(sz, mmc_blocksize_mask) > size) {
Mao Jinlong226f33a2014-07-04 17:24:10 +08004179 fastboot_fail("size too large");
4180 return;
4181 }
4182 else if (mmc_write(ptn , sz, (unsigned int *)data)) {
4183 fastboot_fail("flash write failure");
4184 return;
4185 }
Greg Grisco6e754772011-06-23 12:19:39 -07004186 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07004187 }
4188 fastboot_okay("");
4189 return;
4190}
4191
Ajay Dudanide984792015-03-02 09:57:41 -08004192void cmd_flash_meta_img(const char *arg, void *data, unsigned sz)
4193{
4194 int i, images;
4195 meta_header_t *meta_header;
4196 img_header_entry_t *img_header_entry;
Parth Dixit3e2d3032016-03-04 17:11:52 +05304197 /*End of the image address*/
4198 uintptr_t data_end;
4199
4200 if( (UINT_MAX - sz) > (uintptr_t)data )
4201 data_end = (uintptr_t)data + sz;
4202 else
4203 {
4204 fastboot_fail("Cannot flash: image header corrupt");
4205 return;
4206 }
4207
Ashish Bhimanpalliwar21494e12020-10-07 13:24:03 +05304208 if((UINT_MAX - sizeof(meta_header_t) < (uintptr_t)data) || (data_end < ((uintptr_t)data + sizeof(meta_header_t))))
Parth Dixit3e2d3032016-03-04 17:11:52 +05304209 {
4210 fastboot_fail("Cannot flash: image header corrupt");
4211 return;
4212 }
Ajay Dudanide984792015-03-02 09:57:41 -08004213
lijuang8ee21882016-04-19 16:57:11 +08004214 /* If device is locked:
4215 * Forbid to flash image to avoid the device to bypass the image
4216 * which with "any" name other than bootloader. Because it maybe
4217 * a meta package of all partitions.
4218 */
Monika Singh292b3e92018-03-17 22:40:23 +05304219#if VERIFIED_BOOT || VERIFIED_BOOT_2
lijuang8ee21882016-04-19 16:57:11 +08004220 if (target_build_variant_user()) {
4221 if (!device.is_unlocked) {
4222 fastboot_fail("Device is locked, meta image flashing is not allowed");
4223 return;
4224 }
Mayank Grover889be1b2017-09-12 20:12:23 +05304225
Mayank Grover912eaa62017-10-26 12:08:53 +05304226 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304227 !device.is_unlock_critical)
4228 {
lijuang8ee21882016-04-19 16:57:11 +08004229 fastboot_fail("Device is critical locked, Meta image flashing is not allowed");
4230 return;
4231 }
lijuang8ee21882016-04-19 16:57:11 +08004232 }
4233#endif
4234
Ajay Dudanide984792015-03-02 09:57:41 -08004235 meta_header = (meta_header_t*) data;
Ashish Bhimanpalliwar21494e12020-10-07 13:24:03 +05304236 if(((UINT_MAX - sizeof(meta_header_t) - meta_header->img_hdr_sz) < (uintptr_t)data) || data_end < ((uintptr_t)data + sizeof(meta_header_t) + meta_header->img_hdr_sz))
Parth Dixit3e2d3032016-03-04 17:11:52 +05304237 {
4238 fastboot_fail("Cannot flash: image header corrupt");
4239 return;
4240 }
Ajay Dudanide984792015-03-02 09:57:41 -08004241 img_header_entry = (img_header_entry_t*) (data+sizeof(meta_header_t));
4242
4243 images = meta_header->img_hdr_sz / sizeof(img_header_entry_t);
4244
4245 for (i=0; i<images; i++) {
4246
4247 if((img_header_entry[i].ptn_name == NULL) ||
4248 (img_header_entry[i].start_offset == 0) ||
4249 (img_header_entry[i].size == 0))
4250 break;
Kishor PK49831502017-04-21 17:55:43 +05304251 if ((UINT_MAX - img_header_entry[i].start_offset) < (uintptr_t)data) {
4252 fastboot_fail("Integer overflow detected in start_offset of img");
4253 break;
4254 }
4255 else if ((UINT_MAX - (img_header_entry[i].start_offset + (uintptr_t)data)) < img_header_entry[i].size) {
4256 fastboot_fail("Integer overflow detected in size of img");
4257 break;
4258 }
Parth Dixit3e2d3032016-03-04 17:11:52 +05304259 if( data_end < ((uintptr_t)data + img_header_entry[i].start_offset
4260 + img_header_entry[i].size) )
4261 {
4262 fastboot_fail("Cannot flash: image size mismatch");
4263 break;
4264 }
4265
Ajay Dudanide984792015-03-02 09:57:41 -08004266 cmd_flash_mmc_img(img_header_entry[i].ptn_name,
4267 (void *) data + img_header_entry[i].start_offset,
4268 img_header_entry[i].size);
4269 }
4270
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08004271 if (!strncmp(arg, "bootloader", strlen("bootloader")))
4272 {
4273 strlcpy(device.bootloader_version, TARGET(BOARD), MAX_VERSION_LEN);
4274 strlcat(device.bootloader_version, "-", MAX_VERSION_LEN);
4275 strlcat(device.bootloader_version, meta_header->img_version, MAX_VERSION_LEN);
4276 }
4277 else
4278 {
4279 strlcpy(device.radio_version, TARGET(BOARD), MAX_VERSION_LEN);
4280 strlcat(device.radio_version, "-", MAX_VERSION_LEN);
4281 strlcat(device.radio_version, meta_header->img_version, MAX_VERSION_LEN);
4282 }
4283
4284 write_device_info(&device);
Ajay Dudanide984792015-03-02 09:57:41 -08004285 fastboot_okay("");
4286 return;
4287}
4288
Ajay Dudani5c761132011-04-07 20:19:04 -07004289void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
4290{
4291 unsigned int chunk;
wufeng.jiang813dc352015-06-02 23:02:46 -04004292 uint64_t chunk_data_sz;
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004293 uint32_t *fill_buf = NULL;
4294 uint32_t fill_val;
Mayank Grover4f50bba2017-07-19 18:17:08 +05304295 uint32_t blk_sz_actual = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07004296 sparse_header_t *sparse_header;
4297 chunk_header_t *chunk_header;
Ajay Dudaniab18f022011-05-12 14:39:22 -07004298 uint32_t total_blocks = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07004299 unsigned long long ptn = 0;
Channagoud Kadabi65b91002011-10-11 17:34:33 +05304300 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07004301 int index = INVALID_PTN;
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05304302 uint32_t i;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004303 uint8_t lun = 0;
vijay kumar800255e2015-04-24 20:26:19 +05304304 /*End of the sparse image address*/
Parth Dixit64b1a482016-03-07 16:31:26 +05304305 uintptr_t data_end = (uintptr_t)data + sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07004306
Kinson Chikf1a43512011-07-14 11:28:39 -07004307 index = partition_get_index(arg);
4308 ptn = partition_get_offset(index);
4309 if(ptn == 0) {
Ajay Dudani5c761132011-04-07 20:19:04 -07004310 fastboot_fail("partition table doesn't exist");
4311 return;
4312 }
4313
Channagoud Kadabi65b91002011-10-11 17:34:33 +05304314 size = partition_get_size(index);
Channagoud Kadabi65b91002011-10-11 17:34:33 +05304315
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004316 lun = partition_get_lun(index);
4317 mmc_set_lun(lun);
4318
vijay kumar800255e2015-04-24 20:26:19 +05304319 if (sz < sizeof(sparse_header_t)) {
4320 fastboot_fail("size too low");
4321 return;
4322 }
4323
Ajay Dudani5c761132011-04-07 20:19:04 -07004324 /* Read and skip over sparse image header */
4325 sparse_header = (sparse_header_t *) data;
vijay kumar800255e2015-04-24 20:26:19 +05304326
Mayank Grover48bd9bb2017-07-19 12:04:16 +05304327 if (!sparse_header->blk_sz || (sparse_header->blk_sz % 4)){
4328 fastboot_fail("Invalid block size\n");
4329 return;
4330 }
4331
vijay kumar1321f342015-03-27 12:13:42 +05304332 if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
Ajay Dudani876b3282012-12-21 14:12:17 -08004333 fastboot_fail("size too large");
4334 return;
4335 }
4336
vijay kumarde4fcf62015-04-23 13:05:49 +05304337 data += sizeof(sparse_header_t);
vijay kumar800255e2015-04-24 20:26:19 +05304338
Parth Dixit64b1a482016-03-07 16:31:26 +05304339 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304340 fastboot_fail("buffer overreads occured due to invalid sparse header");
4341 return;
4342 }
4343
vijay kumarde4fcf62015-04-23 13:05:49 +05304344 if(sparse_header->file_hdr_sz != sizeof(sparse_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07004345 {
vijay kumarde4fcf62015-04-23 13:05:49 +05304346 fastboot_fail("sparse header size mismatch");
4347 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07004348 }
4349
Ajay Dudanib06c05f2011-05-12 14:46:10 -07004350 dprintf (SPEW, "=== Sparse Image Header ===\n");
4351 dprintf (SPEW, "magic: 0x%x\n", sparse_header->magic);
4352 dprintf (SPEW, "major_version: 0x%x\n", sparse_header->major_version);
4353 dprintf (SPEW, "minor_version: 0x%x\n", sparse_header->minor_version);
4354 dprintf (SPEW, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
4355 dprintf (SPEW, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
4356 dprintf (SPEW, "blk_sz: %d\n", sparse_header->blk_sz);
4357 dprintf (SPEW, "total_blks: %d\n", sparse_header->total_blks);
4358 dprintf (SPEW, "total_chunks: %d\n", sparse_header->total_chunks);
Ajay Dudani5c761132011-04-07 20:19:04 -07004359
4360 /* Start processing chunks */
4361 for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
4362 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304363 /* Make sure the total image size does not exceed the partition size */
4364 if(((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz) >= size) {
4365 fastboot_fail("size too large");
4366 return;
4367 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004368 /* Read and skip over chunk header */
4369 chunk_header = (chunk_header_t *) data;
4370 data += sizeof(chunk_header_t);
4371
Parth Dixit64b1a482016-03-07 16:31:26 +05304372 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304373 fastboot_fail("buffer overreads occured due to invalid sparse header");
4374 return;
4375 }
4376
Ajay Dudani5c761132011-04-07 20:19:04 -07004377 dprintf (SPEW, "=== Chunk Header ===\n");
4378 dprintf (SPEW, "chunk_type: 0x%x\n", chunk_header->chunk_type);
4379 dprintf (SPEW, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
4380 dprintf (SPEW, "total_size: 0x%x\n", chunk_header->total_sz);
4381
vijay kumar800255e2015-04-24 20:26:19 +05304382 if(sparse_header->chunk_hdr_sz != sizeof(chunk_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07004383 {
vijay kumar800255e2015-04-24 20:26:19 +05304384 fastboot_fail("chunk header size mismatch");
4385 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07004386 }
4387
wufeng.jiang813dc352015-06-02 23:02:46 -04004388 chunk_data_sz = (uint64_t)sparse_header->blk_sz * chunk_header->chunk_sz;
4389
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304390 /* Make sure that the chunk size calculated from sparse image does not
4391 * exceed partition size
4392 */
4393 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + chunk_data_sz > size)
4394 {
4395 fastboot_fail("Chunk data size exceeds partition size");
4396 return;
4397 }
4398
Ajay Dudani5c761132011-04-07 20:19:04 -07004399 switch (chunk_header->chunk_type)
4400 {
4401 case CHUNK_TYPE_RAW:
wufeng.jiang813dc352015-06-02 23:02:46 -04004402 if((uint64_t)chunk_header->total_sz != ((uint64_t)sparse_header->chunk_hdr_sz +
Ajay Dudani5c761132011-04-07 20:19:04 -07004403 chunk_data_sz))
4404 {
4405 fastboot_fail("Bogus chunk size for chunk type Raw");
4406 return;
4407 }
4408
Parth Dixit64b1a482016-03-07 16:31:26 +05304409 if (data_end < (uintptr_t)data + chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05304410 fastboot_fail("buffer overreads occured due to invalid sparse header");
4411 return;
4412 }
4413
wufeng.jiang813dc352015-06-02 23:02:46 -04004414 /* chunk_header->total_sz is uint32,So chunk_data_sz is now less than 2^32
4415 otherwise it will return in the line above
4416 */
Ajay Dudaniab18f022011-05-12 14:39:22 -07004417 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
wufeng.jiang813dc352015-06-02 23:02:46 -04004418 (uint32_t)chunk_data_sz,
Ajay Dudaniab18f022011-05-12 14:39:22 -07004419 (unsigned int*)data))
Ajay Dudani5c761132011-04-07 20:19:04 -07004420 {
4421 fastboot_fail("flash write failure");
4422 return;
4423 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304424 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4425 fastboot_fail("Bogus size for RAW chunk type");
4426 return;
4427 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004428 total_blocks += chunk_header->chunk_sz;
wufeng.jiang813dc352015-06-02 23:02:46 -04004429 data += (uint32_t)chunk_data_sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07004430 break;
4431
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004432 case CHUNK_TYPE_FILL:
4433 if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
4434 sizeof(uint32_t)))
4435 {
4436 fastboot_fail("Bogus chunk size for chunk type FILL");
4437 return;
4438 }
4439
Mayank Grover4f50bba2017-07-19 18:17:08 +05304440 blk_sz_actual = ROUNDUP(sparse_header->blk_sz, CACHE_LINE);
4441 /* Integer overflow detected */
4442 if (blk_sz_actual < sparse_header->blk_sz)
4443 {
4444 fastboot_fail("Invalid block size");
4445 return;
4446 }
4447
4448 fill_buf = (uint32_t *)memalign(CACHE_LINE, blk_sz_actual);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004449 if (!fill_buf)
4450 {
4451 fastboot_fail("Malloc failed for: CHUNK_TYPE_FILL");
4452 return;
4453 }
4454
Parth Dixit64b1a482016-03-07 16:31:26 +05304455 if (data_end < (uintptr_t)data + sizeof(uint32_t)) {
vijay kumar800255e2015-04-24 20:26:19 +05304456 fastboot_fail("buffer overreads occured due to invalid sparse header");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304457 free(fill_buf);
vijay kumar800255e2015-04-24 20:26:19 +05304458 return;
4459 }
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004460 fill_val = *(uint32_t *)data;
4461 data = (char *) data + sizeof(uint32_t);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004462
4463 for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++)
4464 {
4465 fill_buf[i] = fill_val;
4466 }
4467
Gaurav Nebhwanie94cbe12016-03-17 21:16:34 +05304468 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz))
4469 {
4470 fastboot_fail("bogus size for chunk FILL type");
4471 free(fill_buf);
4472 return;
4473 }
4474
wufeng.jiang813dc352015-06-02 23:02:46 -04004475 for (i = 0; i < chunk_header->chunk_sz; i++)
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004476 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304477 /* Make sure that the data written to partition does not exceed partition size */
4478 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + sparse_header->blk_sz > size)
4479 {
4480 fastboot_fail("Chunk data size for fill type exceeds partition size");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304481 free(fill_buf);
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304482 return;
4483 }
4484
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004485 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
4486 sparse_header->blk_sz,
4487 fill_buf))
4488 {
4489 fastboot_fail("flash write failure");
4490 free(fill_buf);
4491 return;
4492 }
4493
4494 total_blocks++;
4495 }
4496
4497 free(fill_buf);
4498 break;
4499
Ajay Dudani5c761132011-04-07 20:19:04 -07004500 case CHUNK_TYPE_DONT_CARE:
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304501 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4502 fastboot_fail("bogus size for chunk DONT CARE type");
4503 return;
4504 }
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004505 total_blocks += chunk_header->chunk_sz;
4506 break;
4507
Ajay Dudani5c761132011-04-07 20:19:04 -07004508 case CHUNK_TYPE_CRC:
4509 if(chunk_header->total_sz != sparse_header->chunk_hdr_sz)
4510 {
wufeng.jiang813dc352015-06-02 23:02:46 -04004511 fastboot_fail("Bogus chunk size for chunk type CRC");
Ajay Dudani5c761132011-04-07 20:19:04 -07004512 return;
4513 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304514 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4515 fastboot_fail("bogus size for chunk CRC type");
4516 return;
4517 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004518 total_blocks += chunk_header->chunk_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304519 if ((uintptr_t)data > UINT_MAX - chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05304520 fastboot_fail("integer overflow occured");
4521 return;
4522 }
wufeng.jiang813dc352015-06-02 23:02:46 -04004523 data += (uint32_t)chunk_data_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304524 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304525 fastboot_fail("buffer overreads occured due to invalid sparse header");
4526 return;
4527 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004528 break;
4529
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004530 default:
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004531 dprintf(CRITICAL, "Unkown chunk type: %x\n",chunk_header->chunk_type);
Ajay Dudani5c761132011-04-07 20:19:04 -07004532 fastboot_fail("Unknown chunk type");
4533 return;
4534 }
4535 }
4536
Ajay Dudani0c6927b2011-05-18 11:12:16 -07004537 dprintf(INFO, "Wrote %d blocks, expected to write %d blocks\n",
4538 total_blocks, sparse_header->total_blks);
4539
4540 if(total_blocks != sparse_header->total_blks)
4541 {
4542 fastboot_fail("sparse image write failure");
4543 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004544
4545 fastboot_okay("");
4546 return;
4547}
4548
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304549static bool CheckVirtualAbCriticalPartition (const char *PartitionName)
4550{
4551 VirtualAbMergeStatus SnapshotMergeStatus;
4552 uint32 Iter = 0;
4553
4554 SnapshotMergeStatus = GetSnapshotMergeStatus ();
4555 if ((SnapshotMergeStatus == MERGING || SnapshotMergeStatus == SNAPSHOTTED)) {
4556 for (Iter = 0; Iter < ARRAY_SIZE (VirtualAbCriticalPartitions); Iter++) {
4557 if (!strncmp (PartitionName, VirtualAbCriticalPartitions[Iter],
4558 strlen (VirtualAbCriticalPartitions[Iter])))
4559 return true;
4560 }
4561 }
4562 return false;
4563}
4564
Ajay Dudani5c761132011-04-07 20:19:04 -07004565void cmd_flash_mmc(const char *arg, void *data, unsigned sz)
4566{
4567 sparse_header_t *sparse_header;
Ajay Dudanide984792015-03-02 09:57:41 -08004568 meta_header_t *meta_header;
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304569 VirtualAbMergeStatus SnapshotMergeStatus;
4570 char FlashResultStr[MAX_RSP_SIZE] = "";
Ajay Dudani5c761132011-04-07 20:19:04 -07004571
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004572#ifdef SSD_ENABLE
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08004573 /* 8 Byte Magic + 2048 Byte xml + Encrypted Data */
4574 unsigned int *magic_number = (unsigned int *) data;
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004575 int ret=0;
4576 uint32 major_version=0;
4577 uint32 minor_version=0;
4578
4579 ret = scm_svc_version(&major_version,&minor_version);
4580 if(!ret)
4581 {
4582 if(major_version >= 2)
4583 {
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004584 if( !strcmp(arg, "ssd") || !strcmp(arg, "tqs") )
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004585 {
4586 ret = encrypt_scm((uint32 **) &data, &sz);
4587 if (ret != 0) {
4588 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4589 return;
4590 }
4591
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004592 /* Protect only for SSD */
4593 if (!strcmp(arg, "ssd")) {
4594 ret = scm_protect_keystore((uint32 *) data, sz);
4595 if (ret != 0) {
4596 dprintf(CRITICAL, "ERROR: scm_protect_keystore Failed\n");
4597 return;
4598 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004599 }
4600 }
4601 else
4602 {
4603 ret = decrypt_scm_v2((uint32 **) &data, &sz);
4604 if(ret != 0)
4605 {
4606 dprintf(CRITICAL,"ERROR: Decryption Failure\n");
4607 return;
4608 }
4609 }
4610 }
4611 else
4612 {
4613 if (magic_number[0] == DECRYPT_MAGIC_0 &&
4614 magic_number[1] == DECRYPT_MAGIC_1)
4615 {
4616 ret = decrypt_scm((uint32 **) &data, &sz);
4617 if (ret != 0) {
4618 dprintf(CRITICAL, "ERROR: Invalid secure image\n");
4619 return;
4620 }
4621 }
4622 else if (magic_number[0] == ENCRYPT_MAGIC_0 &&
4623 magic_number[1] == ENCRYPT_MAGIC_1)
4624 {
4625 ret = encrypt_scm((uint32 **) &data, &sz);
4626 if (ret != 0) {
4627 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4628 return;
4629 }
4630 }
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004631 }
4632 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004633 else
Neeti Desai127b9e02012-03-20 16:11:23 -07004634 {
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004635 dprintf(CRITICAL,"INVALID SVC Version\n");
4636 return;
Neeti Desai127b9e02012-03-20 16:11:23 -07004637 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004638#endif /* SSD_ENABLE */
Neeti Desai127b9e02012-03-20 16:11:23 -07004639
Monika Singh292b3e92018-03-17 22:40:23 +05304640#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07004641 if (target_build_variant_user())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004642 {
lijuang511a2b52015-08-14 20:50:51 +08004643 /* if device is locked:
4644 * common partition will not allow to be flashed
4645 * critical partition will allow to flash image.
4646 */
4647 if(!device.is_unlocked && !critical_flash_allowed(arg)) {
4648 fastboot_fail("Partition flashing is not allowed");
4649 return;
4650 }
Mayank Grover889be1b2017-09-12 20:12:23 +05304651
lijuang511a2b52015-08-14 20:50:51 +08004652 /* if device critical is locked:
4653 * common partition will allow to be flashed
4654 * critical partition will not allow to flash image.
4655 */
Mayank Grover912eaa62017-10-26 12:08:53 +05304656 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304657 !device.is_unlock_critical &&
4658 critical_flash_allowed(arg)) {
4659 fastboot_fail("Critical partition flashing is not allowed");
4660 return;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004661 }
4662 }
4663#endif
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304664
4665 if (target_virtual_ab_supported())
4666 {
4667 if (CheckVirtualAbCriticalPartition (arg)) {
4668 snprintf(FlashResultStr, MAX_RSP_SIZE,"Flashing of %s is not allowed in %s state",
4669 arg, SnapshotMergeState);
4670 fastboot_fail(FlashResultStr);
4671 return;
4672 }
4673
4674 SnapshotMergeStatus = GetSnapshotMergeStatus ();
4675 if (((SnapshotMergeStatus == MERGING) || (SnapshotMergeStatus == SNAPSHOTTED)) &&
4676 !strncmp (arg, "super", strlen ("super"))) {
4677 if(SetSnapshotMergeStatus (CANCELLED))
4678 {
4679 fastboot_fail("Failed to update snapshot state to cancel");
4680 return;
4681 }
4682
4683 //updating fbvar snapshot-merge-state
4684 snprintf(SnapshotMergeState,strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
4685 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
4686 }
4687 }
4688
Monika Singh292b3e92018-03-17 22:40:23 +05304689 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4690 dprintf(INFO, "flashing avb_custom_key\n");
4691 if (store_userkey(data, sz)) {
4692 fastboot_fail("Flashing avb_custom_key failed");
4693 } else {
4694 fastboot_okay("");
4695 }
4696 return;
4697 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004698
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004699 sparse_header = (sparse_header_t *) data;
Ajay Dudanide984792015-03-02 09:57:41 -08004700 meta_header = (meta_header_t *) data;
4701 if (sparse_header->magic == SPARSE_HEADER_MAGIC)
Ajay Dudani5c761132011-04-07 20:19:04 -07004702 cmd_flash_mmc_sparse_img(arg, data, sz);
Ajay Dudanide984792015-03-02 09:57:41 -08004703 else if (meta_header->magic == META_HEADER_MAGIC)
4704 cmd_flash_meta_img(arg, data, sz);
4705 else
4706 cmd_flash_mmc_img(arg, data, sz);
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004707
4708#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +05304709 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304710 (!strncmp(arg, "system", 6)) &&
4711 !device.verity_mode)
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004712 // reset dm_verity mode to enforcing
4713 device.verity_mode = 1;
4714 write_device_info(&device);
Parth Dixitddbc7352015-10-18 03:13:31 +05304715#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004716
Ajay Dudani5c761132011-04-07 20:19:04 -07004717 return;
4718}
4719
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004720void cmd_updatevol(const char *vol_name, void *data, unsigned sz)
4721{
4722 struct ptentry *sys_ptn;
4723 struct ptable *ptable;
4724
4725 ptable = flash_get_ptable();
4726 if (ptable == NULL) {
4727 fastboot_fail("partition table doesn't exist");
4728 return;
4729 }
4730
4731 sys_ptn = ptable_find(ptable, "system");
4732 if (sys_ptn == NULL) {
4733 fastboot_fail("system partition not found");
4734 return;
4735 }
4736
4737 sz = ROUND_TO_PAGE(sz, page_mask);
4738 if (update_ubi_vol(sys_ptn, vol_name, data, sz))
4739 fastboot_fail("update_ubi_vol failed");
4740 else
4741 fastboot_okay("");
4742}
4743
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004744void cmd_flash_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08004745{
4746 struct ptentry *ptn;
4747 struct ptable *ptable;
4748 unsigned extra = 0;
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304749 uint64_t partition_size = 0;
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304750 unsigned bytes_to_round_page = 0;
4751 unsigned rounded_size = 0;
Dima Zavin214cc642009-01-26 11:16:21 -08004752
Kishor PK38ed93d2017-04-25 14:19:26 +05304753 if((uintptr_t)data > (UINT_MAX - sz)) {
4754 fastboot_fail("Cannot flash: image header corrupt");
4755 return;
4756 }
4757
Dima Zavin214cc642009-01-26 11:16:21 -08004758 ptable = flash_get_ptable();
4759 if (ptable == NULL) {
4760 fastboot_fail("partition table doesn't exist");
4761 return;
4762 }
4763
4764 ptn = ptable_find(ptable, arg);
4765 if (ptn == NULL) {
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004766 dprintf(INFO, "unknown partition name (%s). Trying updatevol\n",
4767 arg);
4768 cmd_updatevol(arg, data, sz);
Dima Zavin214cc642009-01-26 11:16:21 -08004769 return;
4770 }
4771
Monika Singh292b3e92018-03-17 22:40:23 +05304772 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4773 dprintf(INFO, "flashing avb_custom_key\n");
4774 if (store_userkey(data, sz)) {
4775 fastboot_fail("Flashing avb_custom_key failed");
4776 } else {
4777 fastboot_okay("");
4778 }
4779 return;
4780 }
4781
Dima Zavin214cc642009-01-26 11:16:21 -08004782 if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) {
Kishor PK38ed93d2017-04-25 14:19:26 +05304783 if((sz > BOOT_MAGIC_SIZE) && (!memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE))) {
4784 dprintf(INFO, "Verified the BOOT_MAGIC in image header \n");
4785 } else {
4786 fastboot_fail("Image is not a boot image");
Dima Zavin214cc642009-01-26 11:16:21 -08004787 return;
4788 }
4789 }
4790
Amol Jadi5c61a952012-05-04 17:05:35 -07004791 if (!strcmp(ptn->name, "system")
Deepa Dinamani13e32c42012-03-12 14:34:17 -07004792 || !strcmp(ptn->name, "userdata")
4793 || !strcmp(ptn->name, "persist")
Sundarajan Srinivasanb063a852013-11-19 14:02:27 -08004794 || !strcmp(ptn->name, "recoveryfs")
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -08004795 || !strcmp(ptn->name, "modem"))
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004796 extra = 1;
Kishor PK38ed93d2017-04-25 14:19:26 +05304797 else {
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304798 rounded_size = ROUNDUP(sz, page_size);
4799 bytes_to_round_page = rounded_size - sz;
4800 if (bytes_to_round_page) {
4801 if (((uintptr_t)data + sz ) > (UINT_MAX - bytes_to_round_page)) {
4802 fastboot_fail("Integer overflow detected");
4803 return;
4804 }
4805 if (((uintptr_t)data + sz + bytes_to_round_page) >
4806 ((uintptr_t)target_get_scratch_address() + target_get_max_flash_size())) {
4807 fastboot_fail("Buffer size is not aligned to page_size");
4808 return;
4809 }
4810 else {
4811 memset(data + sz, 0, bytes_to_round_page);
4812 sz = rounded_size;
4813 }
Kishor PK38ed93d2017-04-25 14:19:26 +05304814 }
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304815 }
4816
Kishor PK38ed93d2017-04-25 14:19:26 +05304817 /*Checking partition_size for the possible integer overflow */
4818 partition_size = validate_partition_size(ptn);
4819
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304820 if (sz > partition_size) {
4821 fastboot_fail("Image size too large");
4822 return;
4823 }
4824
Dima Zavin214cc642009-01-26 11:16:21 -08004825 dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name);
Mayank Grover6cde9352017-06-06 18:45:23 +05304826 if ((sz > UBI_EC_HDR_SIZE) &&
4827 (!memcmp((void *)data, UBI_MAGIC, UBI_MAGIC_SIZE))) {
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004828 if (flash_ubi_img(ptn, data, sz)) {
4829 fastboot_fail("flash write failure");
4830 return;
4831 }
4832 } else {
4833 if (flash_write(ptn, extra, data, sz)) {
4834 fastboot_fail("flash write failure");
4835 return;
4836 }
Dima Zavin214cc642009-01-26 11:16:21 -08004837 }
4838 dprintf(INFO, "partition '%s' updated\n", ptn->name);
4839 fastboot_okay("");
4840}
4841
Kishor PK38ed93d2017-04-25 14:19:26 +05304842
4843static inline uint64_t validate_partition_size(struct ptentry *ptn)
4844{
4845 if (ptn->length && flash_num_pages_per_blk() && page_size) {
4846 if ((ptn->length < ( UINT_MAX / flash_num_pages_per_blk())) && ((ptn->length * flash_num_pages_per_blk()) < ( UINT_MAX / page_size))) {
4847 return ptn->length * flash_num_pages_per_blk() * page_size;
4848 }
4849 }
4850 return 0;
4851}
4852
4853
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004854void cmd_flash(const char *arg, void *data, unsigned sz)
4855{
4856 if(target_is_emmc_boot())
4857 cmd_flash_mmc(arg, data, sz);
4858 else
4859 cmd_flash_nand(arg, data, sz);
4860}
4861
Dima Zavin214cc642009-01-26 11:16:21 -08004862void cmd_continue(const char *arg, void *data, unsigned sz)
4863{
4864 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07004865 fastboot_stop();
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004866
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004867 if (target_is_emmc_boot())
4868 {
lijuanga40d6302015-07-20 20:10:13 +08004869#if FBCON_DISPLAY_MSG
lijuangde34d502016-02-26 16:04:50 +08004870 /* Exit keys' detection thread firstly */
4871 exit_menu_keys_detection();
lijuanga40d6302015-07-20 20:10:13 +08004872#endif
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004873 boot_linux_from_mmc();
4874 }
4875 else
4876 {
4877 boot_linux_from_flash();
4878 }
Dima Zavin214cc642009-01-26 11:16:21 -08004879}
4880
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004881void cmd_reboot(const char *arg, void *data, unsigned sz)
4882{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004883 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004884 fastboot_okay("");
4885 reboot_device(0);
4886}
4887
Mayank Grover351a75e2017-05-30 20:06:08 +05304888void cmd_set_active(const char *arg, void *data, unsigned sz)
4889{
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304890 char *p, *sp = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05304891 unsigned i,current_active_slot;
4892 const char *current_slot_suffix;
4893
4894 if (!partition_multislot_is_supported())
4895 {
4896 fastboot_fail("Command not supported");
4897 return;
4898 }
4899
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304900 if (target_virtual_ab_supported()) {
4901 if (GetSnapshotMergeStatus () == MERGING) {
4902 fastboot_fail ("Slot Change is not allowed in merging state");
4903 return;
4904 }
4905 }
4906
Mayank Grover351a75e2017-05-30 20:06:08 +05304907 if (arg)
4908 {
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304909 p = strtok_r((char *)arg, ":", &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304910 if (p)
Mayank Grover351a75e2017-05-30 20:06:08 +05304911 {
4912 current_active_slot = partition_find_active_slot();
4913
4914 /* Check if trying to make curent slot active */
4915 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304916 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4917 (char *)suffix_delimiter, &sp);
4918
Mayank Grover5eb5f692017-07-19 20:16:04 +05304919 if (current_slot_suffix &&
4920 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304921 {
4922 fastboot_okay("Slot already set active");
4923 return;
4924 }
4925 else
4926 {
4927 for (i = 0; i < AB_SUPPORTED_SLOTS; i++)
4928 {
4929 current_slot_suffix = SUFFIX_SLOT(i);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304930 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4931 (char *)suffix_delimiter, &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304932 if (current_slot_suffix &&
4933 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304934 {
lijuang8b03e5f2019-07-12 18:16:19 +08004935 partition_switch_slots(current_active_slot, i, true);
Mayank Grover351a75e2017-05-30 20:06:08 +05304936 publish_getvar_multislot_vars();
4937 fastboot_okay("");
4938 return;
4939 }
4940 }
4941 }
4942 }
4943 }
4944 fastboot_fail("Invalid slot suffix.");
4945 return;
4946}
4947
Mayank Grover98c4c742019-04-25 17:21:37 +05304948#if DYNAMIC_PARTITION_SUPPORT
4949void cmd_reboot_fastboot(const char *arg, void *data, unsigned sz)
4950{
4951 dprintf(INFO, "rebooting the device - userspace fastboot\n");
4952 if (send_recovery_cmd(RECOVERY_BOOT_FASTBOOT_CMD)) {
4953 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4954 fastboot_fail("Failed to update recovery command");
4955 return;
4956 }
4957 fastboot_okay("");
4958 reboot_device(REBOOT_MODE_UNKNOWN);
4959
4960 //shouldn't come here.
4961 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4962 return;
4963}
4964
4965void cmd_reboot_recovery(const char *arg, void *data, unsigned sz)
4966{
4967 dprintf(INFO, "rebooting the device - recovery\n");
4968 if (send_recovery_cmd(RECOVERY_BOOT_RECOVERY_CMD)) {
4969 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4970 fastboot_fail("Failed to update recovery command");
4971 return;
4972 }
4973 fastboot_okay("");
4974 reboot_device(REBOOT_MODE_UNKNOWN);
4975
4976 //shouldn't come here.
4977 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4978 return;
4979}
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304980
4981#ifdef VIRTUAL_AB_OTA
4982void CmdUpdateSnapshot(const char *arg, void *data, unsigned sz)
4983{
4984 char *command = NULL;
4985 const char *delim = ":";
4986 char *sp;
4987
4988 if (arg) {
4989 command = strtok_r((char *)arg, delim, &sp);
4990 if (command) {
4991 command++;
4992
4993 if(!strncmp (command, "merge", AsciiStrLen ("merge"))) {
4994 if (GetSnapshotMergeStatus () == MERGING) {
4995 cmd_reboot_fastboot(Arg, Data, Size);
4996 }
4997 FastbootOkay ("");
4998 return;
4999 }
5000 else if (!strncmp (Command, "cancel", AsciiStrLen ("cancel"))) {
5001 if(!device.is_unlocked) {
5002 fastboot_fail ("Snapshot Cancel is not allowed in Lock State");
5003 return;
5004 }
5005
5006 if (SetSnapshotMergeStatus (CANCELLED))
5007 {
5008 fastboot_fail("Failed to update snapshot state to cancel");
5009 return;
5010 }
5011
5012 //updating fbvar snapshot-merge-state
5013 snprintf(SnapshotMergeState, strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
5014 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
5015 fastboot_okay("");
5016 return;
5017 }
5018 }
5019 }
5020 fastboot_fail("Invalid snapshot-update command");
5021 return;
5022}
5023#endif
Mayank Grover98c4c742019-04-25 17:21:37 +05305024#endif
5025
Chandan Uddaraju94183c02010-01-15 15:13:59 -08005026void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz)
5027{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005028 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08005029 fastboot_okay("");
5030 reboot_device(FASTBOOT_MODE);
5031}
5032
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005033void cmd_oem_enable_charger_screen(const char *arg, void *data, unsigned size)
5034{
5035 dprintf(INFO, "Enabling charger screen check\n");
5036 device.charger_screen_enabled = 1;
5037 write_device_info(&device);
5038 fastboot_okay("");
5039}
5040
5041void cmd_oem_disable_charger_screen(const char *arg, void *data, unsigned size)
5042{
5043 dprintf(INFO, "Disabling charger screen check\n");
5044 device.charger_screen_enabled = 0;
5045 write_device_info(&device);
5046 fastboot_okay("");
5047}
5048
tracychui9d60fc52020-06-05 17:31:38 +08005049#if defined(ENABLE_PRODINFO_ACCESS)
5050void CmdOemEnableAdb(const char *arg, void *data, unsigned size)
5051{
5052 dprintf(INFO, "Enabling Adb\n");
5053 prod.is_adb_enabled = 1;
5054 write_prod_info(&prod);
5055 fastboot_okay("");
5056}
5057#endif
5058
lijuanga25d8bb2015-09-16 13:11:52 +08005059void cmd_oem_off_mode_charger(const char *arg, void *data, unsigned size)
5060{
5061 char *p = NULL;
5062 const char *delim = " \t\n\r";
Parth Dixit407f15b2016-01-07 14:47:37 +05305063 char *sp;
lijuanga25d8bb2015-09-16 13:11:52 +08005064
5065 if (arg) {
Parth Dixit407f15b2016-01-07 14:47:37 +05305066 p = strtok_r((char *)arg, delim, &sp);
lijuanga25d8bb2015-09-16 13:11:52 +08005067 if (p) {
5068 if (!strncmp(p, "0", 1)) {
5069 device.charger_screen_enabled = 0;
5070 } else if (!strncmp(p, "1", 1)) {
5071 device.charger_screen_enabled = 1;
5072 }
5073 }
5074 }
5075
5076 /* update charger_screen_enabled value for getvar
5077 * command
5078 */
5079 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
5080 device.charger_screen_enabled);
5081
5082 write_device_info(&device);
5083 fastboot_okay("");
5084}
5085
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305086void cmd_oem_select_display_panel(const char *arg, void *data, unsigned size)
5087{
5088 dprintf(INFO, "Selecting display panel %s\n", arg);
5089 if (arg)
5090 strlcpy(device.display_panel, arg,
5091 sizeof(device.display_panel));
5092 write_device_info(&device);
5093 fastboot_okay("");
5094}
5095
Shashank Mittal162244e2011-08-08 19:01:25 -07005096void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
5097{
lijuang4ece1e72015-08-14 21:02:36 +08005098 set_device_unlock(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05305099}
5100
5101void cmd_oem_unlock_go(const char *arg, void *data, unsigned sz)
5102{
lijuang4ece1e72015-08-14 21:02:36 +08005103 if(!device.is_unlocked) {
vijay kumarc65876c2015-04-24 13:29:16 +05305104 if(!is_allow_unlock) {
5105 fastboot_fail("oem unlock is not allowed");
5106 return;
5107 }
5108
lijuang4ece1e72015-08-14 21:02:36 +08005109 set_device_unlock_value(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05305110
lijuang4ece1e72015-08-14 21:02:36 +08005111 /* wipe data */
vijay kumarc65876c2015-04-24 13:29:16 +05305112 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05305113 memset(&msg, 0, sizeof(msg));
vijay kumarc65876c2015-04-24 13:29:16 +05305114 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
5115 write_misc(0, &msg, sizeof(msg));
5116
5117 fastboot_okay("");
5118 reboot_device(RECOVERY_MODE);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07005119 }
5120 fastboot_okay("");
5121}
5122
Channagoud Kadabiad259832015-05-29 11:14:17 -07005123static int aboot_frp_unlock(char *pname, void *data, unsigned sz)
5124{
Mayank Grover70f8b0e2017-05-17 11:49:00 +05305125 int ret=1;
5126 bool authentication_success=false;
Channagoud Kadabiad259832015-05-29 11:14:17 -07005127
Mayank Grover70f8b0e2017-05-17 11:49:00 +05305128 /*
5129 Authentication method not implemented.
5130
5131 OEM to implement, authentication system which on successful validataion,
5132 calls write_allow_oem_unlock() with is_allow_unlock.
5133 */
5134#if 0
5135 authentication_success = oem_specific_auth_mthd();
5136#endif
5137
5138 if (authentication_success)
Channagoud Kadabiad259832015-05-29 11:14:17 -07005139 {
Mayank Grover70f8b0e2017-05-17 11:49:00 +05305140 is_allow_unlock = true;
5141 write_allow_oem_unlock(is_allow_unlock);
5142 ret = 0;
Channagoud Kadabiad259832015-05-29 11:14:17 -07005143 }
5144 return ret;
5145}
5146
Shashank Mittald3e54dd2014-08-28 15:24:02 -07005147void cmd_oem_lock(const char *arg, void *data, unsigned sz)
5148{
lijuang4ece1e72015-08-14 21:02:36 +08005149 set_device_unlock(UNLOCK, FALSE);
Shashank Mittal162244e2011-08-08 19:01:25 -07005150}
5151
Shashank Mittala0032282011-08-26 14:50:11 -07005152void cmd_oem_devinfo(const char *arg, void *data, unsigned sz)
5153{
lijuang511a2b52015-08-14 20:50:51 +08005154 char response[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005155 snprintf(response, sizeof(response), "\tDevice tampered: %s", (device.is_tampered ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07005156 fastboot_info(response);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005157 snprintf(response, sizeof(response), "\tDevice unlocked: %s", (device.is_unlocked ? "true" : "false"));
5158 fastboot_info(response);
Monika Singh292b3e92018-03-17 22:40:23 +05305159#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05305160 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05305161 {
5162 snprintf(response, sizeof(response), "\tDevice critical unlocked: %s",
5163 (device.is_unlock_critical ? "true" : "false"));
5164 fastboot_info(response);
5165 }
Parth Dixitddbc7352015-10-18 03:13:31 +05305166#endif
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005167 snprintf(response, sizeof(response), "\tCharger screen enabled: %s", (device.charger_screen_enabled ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07005168 fastboot_info(response);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305169 snprintf(response, sizeof(response), "\tDisplay panel: %s", (device.display_panel));
5170 fastboot_info(response);
tracychui9d60fc52020-06-05 17:31:38 +08005171#if defined(ENABLE_PRODINFO_ACCESS)
5172 snprintf(response, sizeof(response), "\tAdb enabled: %s", prod.is_adb_enabled ? "true" : "false");
5173 fastboot_info(response);
5174#endif
Shashank Mittala0032282011-08-26 14:50:11 -07005175 fastboot_okay("");
5176}
5177
lijuang511a2b52015-08-14 20:50:51 +08005178void cmd_flashing_get_unlock_ability(const char *arg, void *data, unsigned sz)
5179{
5180 char response[MAX_RSP_SIZE];
5181 snprintf(response, sizeof(response), "\tget_unlock_ability: %d", is_allow_unlock);
5182 fastboot_info(response);
5183 fastboot_okay("");
5184}
5185
5186void cmd_flashing_lock_critical(const char *arg, void *data, unsigned sz)
5187{
lijuang4ece1e72015-08-14 21:02:36 +08005188 set_device_unlock(UNLOCK_CRITICAL, FALSE);
lijuang511a2b52015-08-14 20:50:51 +08005189}
5190
5191void cmd_flashing_unlock_critical(const char *arg, void *data, unsigned sz)
5192{
lijuang4ece1e72015-08-14 21:02:36 +08005193 set_device_unlock(UNLOCK_CRITICAL, TRUE);
lijuang511a2b52015-08-14 20:50:51 +08005194}
5195
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07005196void cmd_preflash(const char *arg, void *data, unsigned sz)
5197{
5198 fastboot_okay("");
5199}
5200
Mao Flynn7b379f32015-04-20 00:28:30 +08005201static uint8_t logo_header[LOGO_IMG_HEADER_SIZE];
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305202
Mao Flynn7b379f32015-04-20 00:28:30 +08005203int splash_screen_check_header(logo_img_header *header)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305204{
Mao Flynn7b379f32015-04-20 00:28:30 +08005205 if (memcmp(header->magic, LOGO_IMG_MAGIC, 8))
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305206 return -1;
Mao Flynn7b379f32015-04-20 00:28:30 +08005207 if (header->width == 0 || header->height == 0)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305208 return -1;
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05305209 if (((header->blocks == 0) || (header->blocks > UINT_MAX/512))) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05305210 return -1;
5211 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305212 return 0;
5213}
5214
Mao Flynn7b379f32015-04-20 00:28:30 +08005215int splash_screen_flash()
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005216{
5217 struct ptentry *ptn;
5218 struct ptable *ptable;
Mao Flynn7b379f32015-04-20 00:28:30 +08005219 struct logo_img_header *header;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005220 struct fbcon_config *fb_display = NULL;
Channagoud Kadabib3ccf5c2014-12-03 12:39:29 -08005221
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305222 ptable = flash_get_ptable();
5223 if (ptable == NULL) {
Mao Flynn7b379f32015-04-20 00:28:30 +08005224 dprintf(CRITICAL, "ERROR: Partition table not found\n");
5225 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305226 }
Mao Flynn7b379f32015-04-20 00:28:30 +08005227
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305228 ptn = ptable_find(ptable, "splash");
5229 if (ptn == NULL) {
5230 dprintf(CRITICAL, "ERROR: splash Partition not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005231 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305232 }
Mao Flynn7b379f32015-04-20 00:28:30 +08005233 if (flash_read(ptn, 0, (void *)logo_header, LOGO_IMG_HEADER_SIZE)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305234 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005235 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305236 }
5237
Mao Flynn7b379f32015-04-20 00:28:30 +08005238 header = (struct logo_img_header *)logo_header;
5239 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305240 dprintf(CRITICAL, "ERROR: Boot image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005241 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305242 }
5243
5244 fb_display = fbcon_display();
5245 if (fb_display) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05305246 if (header->type &&
5247 ((header->blocks * 512) <= (fb_display->width *
5248 fb_display->height * (fb_display->bpp / 8)))) {
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05305249 /* RLE24 compressed data */
Mao Flynn7b379f32015-04-20 00:28:30 +08005250 uint8_t *base = (uint8_t *) fb_display->base + LOGO_IMG_OFFSET;
5251
5252 /* if the logo is full-screen size, remove "fbcon_clear()" */
5253 if ((header->width != fb_display->width)
5254 || (header->height != fb_display->height))
5255 fbcon_clear();
5256
5257 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
5258 (uint32_t *)base,
5259 (header->blocks * 512))) {
5260 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5261 return -1;
5262 }
5263 fbcon_extract_to_screen(header, base);
5264 return 0;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005265 }
Mao Flynn7b379f32015-04-20 00:28:30 +08005266
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07005267 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
5268 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005269 return -1;
5270 }
5271
Vineet Bajaj99291ed2014-09-09 12:29:46 +05305272 uint8_t *base = (uint8_t *) fb_display->base;
Sachin Bhayare619e9e42017-05-15 13:10:31 +05305273 uint32_t fb_size = ROUNDUP(fb_display->width *
5274 fb_display->height *
5275 (fb_display->bpp / 8), 4096);
5276 uint32_t splash_size = ((((header->width * header->height *
5277 fb_display->bpp/8) + 511) >> 9) << 9);
5278
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05305279 if ((header->height * header->width * (fb_display->bpp/8)) > (header->blocks * 512)) {
5280 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
5281 return -1;
5282 }
5283
Sachin Bhayare619e9e42017-05-15 13:10:31 +05305284 if (splash_size > fb_size) {
5285 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
5286 return -1;
5287 }
5288
Mao Flynn7b379f32015-04-20 00:28:30 +08005289 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
5290 (uint32_t *)base,
5291 ((((header->width * header->height * fb_display->bpp/8) + 511) >> 9) << 9))) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305292 fbcon_clear();
Vineet Bajaj99291ed2014-09-09 12:29:46 +05305293 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005294 return -1;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005295 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305296 }
5297
Mao Flynn7b379f32015-04-20 00:28:30 +08005298 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305299}
5300
Mao Flynn7b379f32015-04-20 00:28:30 +08005301int splash_screen_mmc()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305302{
5303 int index = INVALID_PTN;
5304 unsigned long long ptn = 0;
5305 struct fbcon_config *fb_display = NULL;
Mao Flynn7b379f32015-04-20 00:28:30 +08005306 struct logo_img_header *header;
Mao Flynn1893a7f2015-06-03 12:03:36 +08005307 uint32_t blocksize, realsize, readsize;
5308 uint8_t *base;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305309
5310 index = partition_get_index("splash");
5311 if (index == 0) {
5312 dprintf(CRITICAL, "ERROR: splash Partition table not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005313 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305314 }
5315
5316 ptn = partition_get_offset(index);
5317 if (ptn == 0) {
5318 dprintf(CRITICAL, "ERROR: splash Partition invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005319 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305320 }
5321
Mao Flynn1893a7f2015-06-03 12:03:36 +08005322 mmc_set_lun(partition_get_lun(index));
5323
5324 blocksize = mmc_get_device_blocksize();
5325 if (blocksize == 0) {
5326 dprintf(CRITICAL, "ERROR:splash Partition invalid blocksize\n");
5327 return -1;
5328 }
5329
5330 fb_display = fbcon_display();
Channagoud Kadabidaf10a62015-07-22 11:51:55 -07005331 if (!fb_display)
5332 {
5333 dprintf(CRITICAL, "ERROR: fb config is not allocated\n");
5334 return -1;
5335 }
5336
Mao Flynn1893a7f2015-06-03 12:03:36 +08005337 base = (uint8_t *) fb_display->base;
5338
jialongjhan2769d202020-05-22 18:25:56 +08005339 if (mmc_read(ptn , (uint32_t *)(base + LOGO_IMG_OFFSET), blocksize)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305340 dprintf(CRITICAL, "ERROR: Cannot read splash image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005341 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305342 }
Mao Flynn1893a7f2015-06-03 12:03:36 +08005343 header = (struct logo_img_header *)(base + LOGO_IMG_OFFSET);
Mao Flynn7b379f32015-04-20 00:28:30 +08005344 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305345 dprintf(CRITICAL, "ERROR: Splash image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005346 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305347 }
5348
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305349 if (fb_display) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05305350 if (header->type &&
Ashish Bhimanpalliwarce39f482020-10-06 15:27:37 +05305351 (((UINT_MAX - LOGO_IMG_HEADER_SIZE) / 512) >= header->blocks) &&
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05305352 ((header->blocks * 512) <= (fb_display->width *
5353 fb_display->height * (fb_display->bpp / 8)))) {
5354 /* 1 RLE24 compressed data */
Mao Flynn1893a7f2015-06-03 12:03:36 +08005355 base += LOGO_IMG_OFFSET;
Mao Flynn7b379f32015-04-20 00:28:30 +08005356
Mao Flynn1893a7f2015-06-03 12:03:36 +08005357 realsize = header->blocks * 512;
5358 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
5359
5360 /* if the logo is not full-screen size, clean screen */
Mao Flynn7b379f32015-04-20 00:28:30 +08005361 if ((header->width != fb_display->width)
5362 || (header->height != fb_display->height))
5363 fbcon_clear();
5364
Sachin Bhayare619e9e42017-05-15 13:10:31 +05305365 uint32_t fb_size = ROUNDUP(fb_display->width *
5366 fb_display->height *
5367 (fb_display->bpp / 8), 4096);
5368
5369 if (readsize > fb_size) {
5370 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
5371 return -1;
5372 }
5373
jialongjhan2769d202020-05-22 18:25:56 +08005374 if (mmc_read(ptn + blocksize, (uint32_t *)(base + blocksize), readsize)) {
Mao Flynn7b379f32015-04-20 00:28:30 +08005375 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5376 return -1;
5377 }
Mao Flynn7b379f32015-04-20 00:28:30 +08005378
Mao Flynn1893a7f2015-06-03 12:03:36 +08005379 fbcon_extract_to_screen(header, (base + LOGO_IMG_HEADER_SIZE));
5380 } else { /* 2 Raw BGR data */
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305381
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07005382 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
5383 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn1893a7f2015-06-03 12:03:36 +08005384 return -1;
5385 }
5386
5387 realsize = header->width * header->height * fb_display->bpp / 8;
5388 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05305389 if (realsize > (header->blocks * 512)) {
5390 dprintf(CRITICAL, "Logo Size error\n");
5391 return -1;
5392 }
Mao Flynn1893a7f2015-06-03 12:03:36 +08005393
5394 if (blocksize == LOGO_IMG_HEADER_SIZE) { /* read the content directly */
Kishor PKee5c0a32018-03-06 16:49:46 +05305395 if (mmc_read((ptn + PLL_CODES_OFFSET + LOGO_IMG_HEADER_SIZE), (uint32_t *)base, readsize)) {
Mao Flynn1893a7f2015-06-03 12:03:36 +08005396 fbcon_clear();
5397 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5398 return -1;
5399 }
5400 } else {
Kishor PKee5c0a32018-03-06 16:49:46 +05305401 if (mmc_read(ptn + PLL_CODES_OFFSET + blocksize ,
Mao Flynn1893a7f2015-06-03 12:03:36 +08005402 (uint32_t *)(base + LOGO_IMG_OFFSET + blocksize), readsize)) {
5403 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5404 return -1;
5405 }
5406 memmove(base, (base + LOGO_IMG_OFFSET + LOGO_IMG_HEADER_SIZE), realsize);
5407 }
5408 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305409 }
5410
Mao Flynn7b379f32015-04-20 00:28:30 +08005411 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305412}
5413
Mao Flynn7b379f32015-04-20 00:28:30 +08005414int fetch_image_from_partition()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305415{
5416 if (target_is_emmc_boot()) {
5417 return splash_screen_mmc();
5418 } else {
5419 return splash_screen_flash();
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005420 }
5421}
5422
Mayank Grover351a75e2017-05-30 20:06:08 +05305423void publish_getvar_multislot_vars()
5424{
5425 int i,count;
5426 static bool published = false;
5427 static char slot_count[MAX_RSP_SIZE];
5428 static struct ab_slot_info slot_info[AB_SUPPORTED_SLOTS];
5429 static char active_slot_suffix[MAX_RSP_SIZE];
5430 static char has_slot_pname[NUM_PARTITIONS][MAX_GET_VAR_NAME_SIZE];
5431 static char has_slot_reply[NUM_PARTITIONS][MAX_RSP_SIZE];
5432 const char *tmp;
5433 char tmpbuff[MAX_GET_VAR_NAME_SIZE];
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305434 signed active_slt;
Mayank Grover351a75e2017-05-30 20:06:08 +05305435
5436 if (!published)
5437 {
5438 /* Update slot meta info */
5439 count = partition_fill_partition_meta(has_slot_pname, has_slot_reply,
5440 partition_get_partition_count());
5441 for(i=0; i<count; i++)
5442 {
5443 memset(tmpbuff, 0, MAX_GET_VAR_NAME_SIZE);
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305444 snprintf(tmpbuff, MAX_GET_VAR_NAME_SIZE,"has-slot:%s",
5445 has_slot_pname[i]);
5446 strlcpy(has_slot_pname[i], tmpbuff, MAX_GET_VAR_NAME_SIZE);
Mayank Grover351a75e2017-05-30 20:06:08 +05305447 fastboot_publish(has_slot_pname[i], has_slot_reply[i]);
5448 }
5449
5450 for (i=0; i<AB_SUPPORTED_SLOTS; i++)
5451 {
5452 tmp = SUFFIX_SLOT(i);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305453 tmp++; // to remove "_" from slot_suffix.
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305454 snprintf(slot_info[i].slot_is_unbootable, sizeof(slot_info[i].slot_is_unbootable),
5455 "slot-unbootable:%s", tmp);
5456 snprintf(slot_info[i].slot_is_active, sizeof(slot_info[i].slot_is_active),
5457 "slot-active:%s", tmp);
5458 snprintf(slot_info[i].slot_is_succesful, sizeof(slot_info[i].slot_is_succesful),
5459 "slot-success:%s", tmp);
5460 snprintf(slot_info[i].slot_retry_count, sizeof(slot_info[i].slot_retry_count),
5461 "slot-retry-count:%s", tmp);
Mayank Grover351a75e2017-05-30 20:06:08 +05305462 fastboot_publish(slot_info[i].slot_is_unbootable,
5463 slot_info[i].slot_is_unbootable_rsp);
5464 fastboot_publish(slot_info[i].slot_is_active,
5465 slot_info[i].slot_is_active_rsp);
5466 fastboot_publish(slot_info[i].slot_is_succesful,
5467 slot_info[i].slot_is_succesful_rsp);
5468 fastboot_publish(slot_info[i].slot_retry_count,
5469 slot_info[i].slot_retry_count_rsp);
5470 }
5471 fastboot_publish("current-slot", active_slot_suffix);
5472 snprintf(slot_count, sizeof(slot_count),"%d", AB_SUPPORTED_SLOTS);
5473 fastboot_publish("slot-count", slot_count);
5474 published = true;
5475 }
5476
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305477 active_slt = partition_find_active_slot();
5478 if (active_slt != INVALID)
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305479 {
5480 tmp = SUFFIX_SLOT(active_slt);
5481 tmp++; // to remove "_" from slot_suffix.
5482 snprintf(active_slot_suffix, sizeof(active_slot_suffix), "%s", tmp);
5483 }
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305484 else
5485 strlcpy(active_slot_suffix, "INVALID", sizeof(active_slot_suffix));
5486
Mayank Grover351a75e2017-05-30 20:06:08 +05305487 /* Update partition meta information */
5488 partition_fill_slot_meta(slot_info);
5489 return;
5490}
5491
lijuang4ece1e72015-08-14 21:02:36 +08005492void get_product_name(unsigned char *buf)
5493{
5494 snprintf((char*)buf, MAX_RSP_SIZE, "%s", TARGET(BOARD));
5495 return;
5496}
5497
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305498#if PRODUCT_IOT
5499void get_bootloader_version_iot(unsigned char *buf)
5500{
5501 if (buf != NULL)
5502 {
5503 strlcpy(buf, TARGET(BOARD), MAX_VERSION_LEN);
5504 strlcat(buf, "-", MAX_VERSION_LEN);
5505 strlcat(buf, PRODUCT_IOT_VERSION, MAX_VERSION_LEN);
5506 }
5507 return;
5508}
5509#endif
5510
lijuang4ece1e72015-08-14 21:02:36 +08005511void get_bootloader_version(unsigned char *buf)
5512{
jhchena8a15dd2020-04-24 15:45:57 +08005513 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.bootloader_version);
lijuang4ece1e72015-08-14 21:02:36 +08005514 return;
5515}
5516
5517void get_baseband_version(unsigned char *buf)
5518{
jhchena8a15dd2020-04-24 15:45:57 +08005519 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.radio_version);
lijuang4ece1e72015-08-14 21:02:36 +08005520 return;
5521}
5522
Monika Singh32a09f72018-03-14 13:08:29 +05305523bool is_device_locked_critical()
5524{
5525 return device.is_unlock_critical ? false:true;
5526}
5527
lijuang4ece1e72015-08-14 21:02:36 +08005528bool is_device_locked()
5529{
5530 return device.is_unlocked ? false:true;
5531}
5532
Monika Singh32a09f72018-03-14 13:08:29 +05305533bool is_verity_enforcing()
5534{
5535 return device.verity_mode ? true:false;
5536}
5537
Amol Jadi5edf3552013-07-23 14:15:34 -07005538/* register commands and variables for fastboot */
5539void aboot_fastboot_register_commands(void)
5540{
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005541 int i;
lijuangf16461c2015-08-03 17:09:34 +08005542 char hw_platform_buf[MAX_RSP_SIZE];
Rahul Shaharee7baede2021-02-02 13:23:57 +05305543 VirtualAbMergeStatus SnapshotMergeStatus;
Amol Jadi5edf3552013-07-23 14:15:34 -07005544
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005545 struct fastboot_cmd_desc cmd_list[] = {
lijuang511a2b52015-08-14 20:50:51 +08005546 /* By default the enabled list is empty. */
5547 {"", NULL},
5548 /* move commands enclosed within the below ifndef to here
5549 * if they need to be enabled in user build.
5550 */
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005551#ifndef DISABLE_FASTBOOT_CMDS
lijuang511a2b52015-08-14 20:50:51 +08005552 /* Register the following commands only for non-user builds */
5553 {"flash:", cmd_flash},
5554 {"erase:", cmd_erase},
5555 {"boot", cmd_boot},
5556 {"continue", cmd_continue},
5557 {"reboot", cmd_reboot},
5558 {"reboot-bootloader", cmd_reboot_bootloader},
5559 {"oem unlock", cmd_oem_unlock},
5560 {"oem unlock-go", cmd_oem_unlock_go},
5561 {"oem lock", cmd_oem_lock},
5562 {"flashing unlock", cmd_oem_unlock},
5563 {"flashing lock", cmd_oem_lock},
5564 {"flashing lock_critical", cmd_flashing_lock_critical},
5565 {"flashing unlock_critical", cmd_flashing_unlock_critical},
5566 {"flashing get_unlock_ability", cmd_flashing_get_unlock_ability},
5567 {"oem device-info", cmd_oem_devinfo},
5568 {"preflash", cmd_preflash},
5569 {"oem enable-charger-screen", cmd_oem_enable_charger_screen},
5570 {"oem disable-charger-screen", cmd_oem_disable_charger_screen},
lijuanga25d8bb2015-09-16 13:11:52 +08005571 {"oem off-mode-charge", cmd_oem_off_mode_charger},
lijuang511a2b52015-08-14 20:50:51 +08005572 {"oem select-display-panel", cmd_oem_select_display_panel},
Mayank Grover6ccc1c92017-07-04 17:36:46 +05305573 {"set_active",cmd_set_active},
Mayank Grover98c4c742019-04-25 17:21:37 +05305574#if DYNAMIC_PARTITION_SUPPORT
5575 {"reboot-fastboot",cmd_reboot_fastboot},
5576 {"reboot-recovery",cmd_reboot_recovery},
5577#endif
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05305578#ifdef VIRTUAL_AB_OTA
5579 {"snapshot-update", CmdUpdateSnapshot},
5580#endif
Channagoud Kadabi736c4962015-08-21 11:56:52 -07005581#if UNITTEST_FW_SUPPORT
Channagoud Kadabid5ddf482015-09-28 10:31:35 -07005582 {"oem run-tests", cmd_oem_runtests},
Channagoud Kadabi736c4962015-08-21 11:56:52 -07005583#endif
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005584#endif
tracychui9d60fc52020-06-05 17:31:38 +08005585#if defined(ENABLE_PRODINFO_ACCESS)
5586 {"oem adb_enable", CmdOemEnableAdb},
5587#endif
lijuang511a2b52015-08-14 20:50:51 +08005588 };
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005589
5590 int fastboot_cmds_count = sizeof(cmd_list)/sizeof(cmd_list[0]);
5591 for (i = 1; i < fastboot_cmds_count; i++)
5592 fastboot_register(cmd_list[i].name,cmd_list[i].cb);
5593
Amol Jadi5edf3552013-07-23 14:15:34 -07005594 /* publish variables and their values */
5595 fastboot_publish("product", TARGET(BOARD));
5596 fastboot_publish("kernel", "lk");
5597 fastboot_publish("serialno", sn_buf);
5598
Mayank Grovera64dfbe2018-05-17 14:06:34 +05305599 /*publish hw-revision major(upper 16 bits) and minor(lower 16 bits)*/
5600 snprintf(soc_version_str, MAX_RSP_SIZE, "%x", board_soc_version());
5601 fastboot_publish("hw-revision", soc_version_str);
5602
Amol Jadi5edf3552013-07-23 14:15:34 -07005603 /*
5604 * partition info is supported only for emmc partitions
5605 * Calling this for NAND prints some error messages which
5606 * is harmless but misleading. Avoid calling this for NAND
5607 * devices.
5608 */
5609 if (target_is_emmc_boot())
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305610 publish_getvar_partition_info(part_info, partition_get_partition_count());
Amol Jadi5edf3552013-07-23 14:15:34 -07005611
Mayank Grover351a75e2017-05-30 20:06:08 +05305612 if (partition_multislot_is_supported())
5613 publish_getvar_multislot_vars();
5614
Amol Jadi5edf3552013-07-23 14:15:34 -07005615 /* Max download size supported */
lijuang2fbed912019-07-12 14:15:05 +08005616#if !VERIFIED_BOOT_2
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005617 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5618 target_get_max_flash_size());
lijuang2fbed912019-07-12 14:15:05 +08005619#else
5620 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5621 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5622#endif
5623
Amol Jadi5edf3552013-07-23 14:15:34 -07005624 fastboot_publish("max-download-size", (const char *) max_download_size);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005625 /* Is the charger screen check enabled */
5626 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
5627 device.charger_screen_enabled);
5628 fastboot_publish("charger-screen-enabled",
5629 (const char *) charger_screen_enabled);
tracychui9d60fc52020-06-05 17:31:38 +08005630#if defined(ENABLE_PRODINFO_ACCESS)
5631 read_prod_info(&prod);
5632 snprintf(AdbEnable, MAX_RSP_SIZE, "%d",
5633 prod.is_adb_enabled);
5634 fastboot_publish("adb-enabled",
5635 (const char *) AdbEnable);
5636#endif
lijuanga25d8bb2015-09-16 13:11:52 +08005637 fastboot_publish("off-mode-charge", (const char *) charger_screen_enabled);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305638 snprintf(panel_display_mode, MAX_RSP_SIZE, "%s",
5639 device.display_panel);
5640 fastboot_publish("display-panel",
5641 (const char *) panel_display_mode);
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +05305642
5643 if (target_is_emmc_boot())
5644 {
5645 mmc_blocksize = mmc_get_device_blocksize();
5646 }
5647 else
5648 {
5649 mmc_blocksize = flash_block_size();
5650 }
5651 snprintf(block_size_string, MAX_RSP_SIZE, "0x%x", mmc_blocksize);
5652 fastboot_publish("erase-block-size", (const char *) block_size_string);
5653 fastboot_publish("logical-block-size", (const char *) block_size_string);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305654#if PRODUCT_IOT
5655 get_bootloader_version_iot(&bootloader_version_string);
5656 fastboot_publish("version-bootloader", (const char *) bootloader_version_string);
5657
5658 /* Version baseband is n/a for apq iot devices */
5659 fastboot_publish("version-baseband", "N/A");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305660#else
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08005661 fastboot_publish("version-bootloader", (const char *) device.bootloader_version);
5662 fastboot_publish("version-baseband", (const char *) device.radio_version);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305663#endif
lijuangf16461c2015-08-03 17:09:34 +08005664 fastboot_publish("secure", is_secure_boot_enable()? "yes":"no");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305665 fastboot_publish("unlocked", device.is_unlocked ? "yes":"no");
lijuangf16461c2015-08-03 17:09:34 +08005666 smem_get_hw_platform_name((unsigned char *) hw_platform_buf, sizeof(hw_platform_buf));
5667 snprintf(get_variant, MAX_RSP_SIZE, "%s %s", hw_platform_buf,
5668 target_is_emmc_boot()? "eMMC":"UFS");
5669 fastboot_publish("variant", (const char *) get_variant);
lijuang65c5a822015-08-29 16:35:36 +08005670#if CHECK_BAT_VOLTAGE
lijuang102dfa92015-10-09 18:31:03 +08005671 update_battery_status();
lijuang65c5a822015-08-29 16:35:36 +08005672 fastboot_publish("battery-voltage", (const char *) battery_voltage);
lijuang102dfa92015-10-09 18:31:03 +08005673 fastboot_publish("battery-soc-ok", (const char *) battery_soc_ok);
lijuang65c5a822015-08-29 16:35:36 +08005674#endif
Mayank Grover98c4c742019-04-25 17:21:37 +05305675 if (target_dynamic_partition_supported())
5676 fastboot_publish("is-userspace", "no");
Rahul Shaharee7baede2021-02-02 13:23:57 +05305677
5678 if (target_virtual_ab_supported()) {
5679 SnapshotMergeStatus = GetSnapshotMergeStatus ();
5680
5681 switch (SnapshotMergeStatus) {
5682 case SNAPSHOTTED:
5683 SnapshotMergeStatus = SNAPSHOTTED;
5684 break;
5685 case MERGING:
5686 SnapshotMergeStatus = MERGING;
5687 break;
5688 default:
5689 SnapshotMergeStatus = NONE_MERGE_STATUS;
5690 break;
5691 }
5692
5693 snprintf(SnapshotMergeState,
5694 strlen(VabSnapshotMergeStatus[SnapshotMergeStatus]) + 1,
5695 "%s", VabSnapshotMergeStatus[SnapshotMergeStatus]);
5696 fastboot_publish("snapshot-update-state", SnapshotMergeState);
5697 }
Amol Jadi5edf3552013-07-23 14:15:34 -07005698}
5699
Brian Swetland9c4c0752009-01-25 16:23:50 -08005700void aboot_init(const struct app_descriptor *app)
5701{
Shashank Mittal4f99a882010-02-01 13:58:50 -08005702 unsigned reboot_mode = 0;
Mayank Grover351a75e2017-05-30 20:06:08 +05305703 int boot_err_type = 0;
5704 int boot_slot = INVALID;
jessicatseng43b1e352020-05-26 13:17:56 +08005705 int vbat = 0;
5706 char boot_vbat[MAX_RSP_SIZE];
Chandan Uddarajubedca152010-06-02 23:05:15 -07005707
lijuang39831732016-01-08 17:49:02 +08005708 /* Initialise wdog to catch early lk crashes */
5709#if WDOG_SUPPORT
5710 msm_wdog_init();
5711#endif
5712
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005713 /* Setup page size information for nv storage */
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005714 if (target_is_emmc_boot())
5715 {
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005716 page_size = mmc_page_size();
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005717 page_mask = page_size - 1;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05305718 mmc_blocksize = mmc_get_device_blocksize();
5719 mmc_blocksize_mask = mmc_blocksize - 1;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005720 }
5721 else
5722 {
5723 page_size = flash_page_size();
5724 page_mask = page_size - 1;
5725 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07005726 ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
5727
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005728 read_device_info(&device);
tracychui9d60fc52020-06-05 17:31:38 +08005729#if defined(ENABLE_PRODINFO_ACCESS)
5730 read_prod_info(&prod);
5731#endif
vijay kumarc65876c2015-04-24 13:29:16 +05305732 read_allow_oem_unlock(&device);
Shashank Mittal162244e2011-08-08 19:01:25 -07005733
Mayank Grover351a75e2017-05-30 20:06:08 +05305734 /* Detect multi-slot support */
5735 if (partition_multislot_is_supported())
5736 {
5737 boot_slot = partition_find_active_slot();
5738 if (boot_slot == INVALID)
5739 {
5740 boot_into_fastboot = true;
5741 dprintf(INFO, "Active Slot: (INVALID)\n");
5742 }
5743 else
5744 {
5745 /* Setting the state of system to boot active slot */
5746 partition_mark_active_slot(boot_slot);
5747 dprintf(INFO, "Active Slot: (%s)\n", SUFFIX_SLOT(boot_slot));
5748 }
5749 }
5750
Greg Griscod6250552011-06-29 14:40:23 -07005751 target_serialno((unsigned char *) sn_buf);
tracychui9d60fc52020-06-05 17:31:38 +08005752#if defined(ENABLE_PRODINFO_ACCESS)
5753 dprintf(CRITICAL,"serial number: %s\n",sn_buf);
5754#else
Ajay Dudanib06c05f2011-05-12 14:46:10 -07005755 dprintf(SPEW,"serial number: %s\n",sn_buf);
tracychui9d60fc52020-06-05 17:31:38 +08005756#endif
5757#if defined(ENABLE_PRODINFO_ACCESS)
5758 read_prod_info(&prod);
5759 snprintf((char *)cust_sn_buf, PRODINFO_MAX_SSN_LEN + 1, "%s", prod.ssn);
5760 dprintf(CRITICAL,"customer serial number: %s\n", cust_sn_buf);
5761 snprintf((char *)factory_sn_buf, PRODINFO_MAX_ISN_LEN + 1, "%s", prod.isn);
5762 dprintf(CRITICAL,"factory serial number: %s\n", factory_sn_buf);
5763#endif
Dhaval Patel223ec952013-07-18 14:49:44 -07005764 memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE);
5765
Matthew Qindefd5562014-07-11 18:02:40 +08005766 /*
5767 * Check power off reason if user force reset,
5768 * if yes phone will do normal boot.
5769 */
5770 if (is_user_force_reset())
5771 goto normal_boot;
5772
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005773 /* Check if we should do something other than booting up */
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005774 if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005775 {
Pavel Nedeva4c9d3a2013-05-15 14:42:34 +03005776 dprintf(ALWAYS,"dload mode key sequence detected\n");
lijuang395b5e62015-11-19 17:39:44 +08005777 reboot_device(EMERGENCY_DLOAD);
5778 dprintf(CRITICAL,"Failed to reboot into dload mode\n");
5779
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005780 boot_into_fastboot = true;
5781 }
5782 if (!boot_into_fastboot)
5783 {
5784 if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
5785 boot_into_recovery = 1;
5786 if (!boot_into_recovery &&
5787 (keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
Pavel Nedev5d91d412013-04-29 11:34:24 +03005788 boot_into_fastboot = true;
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005789 }
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005790 #if NO_KEYPAD_DRIVER
Kinson Chik0b1c8162011-08-31 16:31:57 -07005791 if (fastboot_trigger())
Pavel Nedev5d91d412013-04-29 11:34:24 +03005792 boot_into_fastboot = true;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005793 #endif
Chandan Uddarajubedca152010-06-02 23:05:15 -07005794
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005795#if USE_PON_REBOOT_REG
5796 reboot_mode = check_hard_reboot_mode();
5797#else
Ajay Dudani77421292010-10-27 19:34:06 -07005798 reboot_mode = check_reboot_mode();
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005799#endif
5800 if (reboot_mode == RECOVERY_MODE)
5801 {
Ajay Dudani77421292010-10-27 19:34:06 -07005802 boot_into_recovery = 1;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005803 }
5804 else if(reboot_mode == FASTBOOT_MODE)
5805 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005806 boot_into_fastboot = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005807 }
5808 else if(reboot_mode == ALARM_BOOT)
5809 {
Matthew Qind886f3c2014-01-17 16:52:01 +08005810 boot_reason_alarm = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005811 }
Monika Singhb0db4b82018-09-26 12:18:02 +05305812#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05305813 else if (VB_M <= target_get_vb_version())
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005814 {
Mayank Grover889be1b2017-09-12 20:12:23 +05305815 if (reboot_mode == DM_VERITY_ENFORCING)
5816 {
5817 device.verity_mode = 1;
5818 write_device_info(&device);
5819 }
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005820#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05305821 else if (reboot_mode == DM_VERITY_EIO)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005822#else
Mayank Grover889be1b2017-09-12 20:12:23 +05305823 else if (reboot_mode == DM_VERITY_LOGGING)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005824#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05305825 {
5826 device.verity_mode = 0;
5827 write_device_info(&device);
5828 }
5829 else if (reboot_mode == DM_VERITY_KEYSCLEAR)
5830 {
5831 if(send_delete_keys_to_tz())
5832 ASSERT(0);
5833 }
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005834 }
Parth Dixitddbc7352015-10-18 03:13:31 +05305835#endif
Ajay Dudani77421292010-10-27 19:34:06 -07005836
jialongjhan2769d202020-05-22 18:25:56 +08005837 /* Display splash screen if enabled */
5838#if DISPLAY_SPLASH_SCREEN
5839#if NO_ALARM_DISPLAY
5840 if (!check_alarm_boot()) {
5841#endif
5842 dprintf(SPEW, "Display Init: Start\n");
5843#if DISPLAY_HDMI_PRIMARY
5844 if (!strlen(device.display_panel))
5845 strlcpy(device.display_panel, DISPLAY_PANEL_HDMI,
5846 sizeof(device.display_panel));
5847#endif
5848#if ENABLE_WBC
5849 /* Wait if the display shutdown is in progress */
5850 while(pm_app_display_shutdown_in_prgs());
5851 if (!pm_appsbl_display_init_done())
5852 target_display_init(device.display_panel);
5853 else
5854 display_image_on_screen();
5855#else
5856 target_display_init(device.display_panel);
5857#endif
5858 dprintf(SPEW, "Display Init: Done\n");
5859#if NO_ALARM_DISPLAY
5860 }
5861#endif
5862#endif
5863
5864
Matthew Qindefd5562014-07-11 18:02:40 +08005865normal_boot:
Pavel Nedev5d91d412013-04-29 11:34:24 +03005866 if (!boot_into_fastboot)
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005867 {
jessicatseng43b1e352020-05-26 13:17:56 +08005868 if(!target_pause_for_battery_charge())
5869 {
5870 vbat = target_get_battery_voltage();
5871 snprintf(boot_vbat, MAX_RSP_SIZE, "%d", vbat);
5872 dprintf(CRITICAL,"battery_voltage: %s\n", boot_vbat);
5873 if(vbat < 3500000)
5874 {
5875 display_lowbattery_image_on_screen();
5876 //[Arima][8901][JialongJhan] Command mode reflash screen when low battery logo shown 20190516 Start
5877 msm_display_flush();
5878 //[Arima][8901][JialongJhan] Command mode reflash screen when low battery logo shown 20190516 End
5879 dprintf(CRITICAL,"Low battery, cannot boot up...\n");
5880 mdelay(3000);
5881 shutdown_device();
5882 }
5883 }
5884
Pavel Nedev5d91d412013-04-29 11:34:24 +03005885 if (target_is_emmc_boot())
Shashank Mittala0032282011-08-26 14:50:11 -07005886 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005887 if(emmc_recovery_init())
5888 dprintf(ALWAYS,"error in emmc_recovery_init\n");
5889 if(target_use_signed_kernel())
Shashank Mittala0032282011-08-26 14:50:11 -07005890 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005891 if((device.is_unlocked) || (device.is_tampered))
5892 {
5893 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05305894 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Pavel Nedev5d91d412013-04-29 11:34:24 +03005895 #endif
5896 #if USE_PCOM_SECBOOT
5897 set_tamper_flag(device.is_tampered);
5898 #endif
5899 }
Shashank Mittala0032282011-08-26 14:50:11 -07005900 }
Amit Blay6281ebc2015-01-11 14:44:08 +02005901
Mayank Grover351a75e2017-05-30 20:06:08 +05305902retry_boot:
5903 /* Trying to boot active partition */
5904 if (partition_multislot_is_supported())
5905 {
5906 boot_slot = partition_find_boot_slot();
5907 partition_mark_active_slot(boot_slot);
5908 if (boot_slot == INVALID)
5909 goto fastboot;
5910 }
5911
5912 boot_err_type = boot_linux_from_mmc();
5913 switch (boot_err_type)
5914 {
5915 case ERR_INVALID_PAGE_SIZE:
5916 case ERR_DT_PARSE:
5917 case ERR_ABOOT_ADDR_OVERLAP:
Mayank Grover10cabbe2017-10-30 19:11:05 +05305918 case ERR_INVALID_BOOT_MAGIC:
Mayank Grover351a75e2017-05-30 20:06:08 +05305919 if(partition_multislot_is_supported())
Mayank Grover10cabbe2017-10-30 19:11:05 +05305920 {
5921 /*
5922 * Deactivate current slot, as it failed to
5923 * boot, and retry next slot.
5924 */
5925 partition_deactivate_slot(boot_slot);
Mayank Grover351a75e2017-05-30 20:06:08 +05305926 goto retry_boot;
Mayank Grover10cabbe2017-10-30 19:11:05 +05305927 }
Mayank Grover351a75e2017-05-30 20:06:08 +05305928 else
5929 break;
Mayank Grover351a75e2017-05-30 20:06:08 +05305930 default:
5931 break;
5932 /* going to fastboot menu */
5933 }
Shashank Mittala0032282011-08-26 14:50:11 -07005934 }
Pavel Nedev5d91d412013-04-29 11:34:24 +03005935 else
5936 {
5937 recovery_init();
5938 #if USE_PCOM_SECBOOT
5939 if((device.is_unlocked) || (device.is_tampered))
5940 set_tamper_flag(device.is_tampered);
5941 #endif
5942 boot_linux_from_flash();
5943 }
5944 dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
5945 "to fastboot mode.\n");
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005946 }
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005947
Mayank Grover351a75e2017-05-30 20:06:08 +05305948fastboot:
jialongjhan2769d202020-05-22 18:25:56 +08005949
5950 mdelay(1000);
5951
Amol Jadi5edf3552013-07-23 14:15:34 -07005952 /* We are here means regular boot did not happen. Start fastboot. */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07005953
Amol Jadi5edf3552013-07-23 14:15:34 -07005954 /* register aboot specific fastboot commands */
5955 aboot_fastboot_register_commands();
Amol Jadi57abe4c2011-05-24 15:47:27 -07005956
Amol Jadi5edf3552013-07-23 14:15:34 -07005957 /* dump partition table for debug info */
Kinson Chikf1a43512011-07-14 11:28:39 -07005958 partition_dump();
Amol Jadi5edf3552013-07-23 14:15:34 -07005959
5960 /* initialize and start fastboot */
Saranya Chidura41b34532018-10-16 12:29:52 +05305961#if !VERIFIED_BOOT_2
Amol Jadi5edf3552013-07-23 14:15:34 -07005962 fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
Saranya Chidura41b34532018-10-16 12:29:52 +05305963#else
5964 /* Add salt buffer offset at start of image address to copy VB salt */
5965 fastboot_init(ADD_SALT_BUFF_OFFSET(target_get_scratch_address()),
5966 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5967#endif
lijuang4ece1e72015-08-14 21:02:36 +08005968#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08005969 display_fastboot_menu();
lijuang4ece1e72015-08-14 21:02:36 +08005970#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08005971}
5972
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07005973uint32_t get_page_size()
5974{
5975 return page_size;
5976}
5977
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005978/*
5979 * Calculated and save hash (SHA256) for non-signed boot image.
5980 *
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005981 * @param image_addr - Boot image address
5982 * @param image_size - Size of the boot image
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005983 *
5984 * @return int - 0 on success, negative value on failure.
5985 */
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005986static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size)
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005987{
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005988 unsigned int digest[8];
5989#if IMAGE_VERIF_ALGO_SHA1
5990 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
5991#else
5992 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
5993#endif
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005994
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005995 target_crypto_init_params();
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08005996 hash_find((unsigned char *) image_addr, image_size, (unsigned char *)&digest, auth_algo);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005997
5998 save_kernel_hash_cmd(digest);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005999 dprintf(INFO, "aboot_save_boot_hash_mmc: imagesize_actual size %d bytes.\n", (int) image_size);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03006000
6001 return 0;
6002}
6003
Mayank Grover351a75e2017-05-30 20:06:08 +05306004
Brian Swetland9c4c0752009-01-25 16:23:50 -08006005APP_START(aboot)
6006 .init = aboot_init,
6007APP_END