blob: bea2b13da3146bde5604f0fb57e15e0f3b163f94 [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
tedwub36be742020-07-03 18:02:48 +0800241#define RF_VARIANT_PIN_0 89
242#define RF_VARIANT_PIN_1 141
243
244static const char *rfvar_prefix = " androidboot.rfvariant=";
245static const char *rfvar_0 = "B13";
246static const char *rfvar_1 = "B28B";
247static const char *rfvar_2 = "B28A";
248static const char *rfvar_3 = "03";
249
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700250#if VERIFIED_BOOT
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700251static const char *verity_mode = " androidboot.veritymode=";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700252static const char *verified_state= " androidboot.verifiedbootstate=";
Parth Dixita5715a02015-10-29 12:25:10 +0530253static const char *keymaster_v1= " androidboot.keymaster=1";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700254//indexed based on enum values, green is 0 by default
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700255
256struct verified_boot_verity_mode vbvm[] =
257{
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700258#if ENABLE_VB_ATTEST
259 {false, "eio"},
260#else
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700261 {false, "logging"},
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700262#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700263 {true, "enforcing"},
264};
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700265struct verified_boot_state_name vbsn[] =
266{
267 {GREEN, "green"},
268 {ORANGE, "orange"},
269 {YELLOW,"yellow"},
270 {RED,"red" },
271};
272#endif
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700273/*As per spec delay wait time before shutdown in Red state*/
274#define DELAY_WAIT 30000
Ashish Bhimanpalliwar8cb34fd2020-11-12 19:26:41 +0530275static unsigned page_size = BOARD_KERNEL_PAGESIZE;
276
277uint32_t kernel_hdr_page_size()
278{
279 return page_size;
280}
281
282
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700283static unsigned page_mask = 0;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +0530284static unsigned mmc_blocksize = 0;
285static unsigned mmc_blocksize_mask = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700286static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
287static bool boot_into_ffbm;
vijay kumar870515d2015-08-31 16:37:24 +0530288static char *target_boot_params = NULL;
Matthew Qind886f3c2014-01-17 16:52:01 +0800289static bool boot_reason_alarm;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -0700290static bool devinfo_present = true;
tracychui9d60fc52020-06-05 17:31:38 +0800291#if defined(ENABLE_PRODINFO_ACCESS)
292static bool prodinfo_present = true;
293#endif
Channagoud Kadabi736c4962015-08-21 11:56:52 -0700294bool boot_into_fastboot = false;
Parth Dixit4097b622016-03-15 14:42:27 +0530295static uint32_t dt_size = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530296static char *vbcmdline;
297static bootinfo info = {0};
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530298static void *recovery_dtbo_buf = NULL;
299static uint32_t recovery_dtbo_size = 0;
300
Shashank Mittalcd98d472011-08-02 14:29:24 -0700301/* Assuming unauthorized kernel image by default */
302static int auth_kernel_img = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530303static device_info device = {DEVICE_MAGIC,0,0,0,0,{0},{0},{0},1,{0},0,{0}};
304
tracychui9d60fc52020-06-05 17:31:38 +0800305#if defined(ENABLE_PRODINFO_ACCESS)
306static prod_info prod = {PRODINFO_MAGIC, {0}, {0}, 0};
307#endif
308
jhchena8a15dd2020-04-24 15:45:57 +0800309#ifdef ENABLE_FUSE_CHECK
310static const char *fuse_blown = " androidboot.oem.color=red";
311static const char *fuse_not_blown = " androidboot.oem.color=brown";
312#endif
313
314#ifdef ENABLE_FUSE_CHECK
315 int is_fused = 0;
316#endif
317
vijay kumarc65876c2015-04-24 13:29:16 +0530318static bool is_allow_unlock = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -0700319
vijay kumarca2e6812015-07-08 20:28:25 +0530320static char frp_ptns[2][8] = {"config","frp"};
321
lijuang511a2b52015-08-14 20:50:51 +0800322static const char *critical_flash_allowed_ptn[] = {
323 "aboot",
324 "rpm",
325 "tz",
326 "sbl",
327 "sdi",
328 "sbl1",
329 "xbl",
330 "hyp",
331 "pmic",
332 "bootloader",
333 "devinfo",
334 "partition"};
335
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +0530336static const char *VirtualAbCriticalPartitions[] = {
337 "misc",
338 "metadata",
339 "userdata"};
340
341static bool CheckVirtualAbCriticalPartition (const char *PartitionName);
342
Rahul Shaharee7baede2021-02-02 13:23:57 +0530343static const char *VabSnapshotMergeStatus[] = {
344 "none",
345 "unknown",
346 "snapshotted",
347 "merging",
348 "cancelled"};
349
Dima Zavin42168f22009-01-30 11:52:22 -0800350struct atag_ptbl_entry
351{
352 char name[16];
353 unsigned offset;
354 unsigned size;
355 unsigned flags;
356};
357
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700358/*
359 * Partition info, required to be published
360 * for fastboot
361 */
362struct getvar_partition_info {
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530363 char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700364 char getvar_size[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for size */
365 char getvar_type[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for type */
366 char size_response[MAX_RSP_SIZE]; /* fastboot response for size */
367 char type_response[MAX_RSP_SIZE]; /* fastboot response for type */
368};
369
370/*
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530371 * Update the part_type_known for known paritions types.
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700372 */
Mayank Groverd38fe012018-03-13 15:33:16 +0530373#define RAW_STR "raw"
Mayank Grover52cd10a2018-03-15 12:57:54 +0530374#define EXT_STR "ext4"
375#define F2FS_STR "f2fs"
376
377#define FS_SUPERBLOCK_OFFSET 0x400
378#define EXT_MAGIC 0xEF53
379#define EXT_MAGIC_OFFSET_SB 0x38
380#define F2FS_MAGIC 0xF2F52010 // F2FS Magic Number
381#define F2FS_MAGIC_OFFSET_SB 0x0
382
383typedef enum fs_signature_type {
384 EXT_FS_SIGNATURE = 1,
385 EXT_F2FS_SIGNATURE = 2,
386 NO_FS = -1
387} fs_signature_type;
388
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530389struct getvar_partition_info part_info[NUM_PARTITIONS];
390struct getvar_partition_info part_type_known[] =
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700391{
Mayank Grover49920212018-02-09 18:15:55 +0530392 { "system" , "partition-size:", "partition-type:", "", "ext4" },
393 { "userdata" , "partition-size:", "partition-type:", "", "ext4" },
394 { "cache" , "partition-size:", "partition-type:", "", "ext4" },
395 { "recoveryfs" , "partition-size:", "partition-type:", "", "ext4" },
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700396};
397
398char max_download_size[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -0700399char charger_screen_enabled[MAX_RSP_SIZE];
tracychui9d60fc52020-06-05 17:31:38 +0800400#if defined(ENABLE_PRODINFO_ACCESS)
401char cust_sn_buf[PRODINFO_MAX_SSN_LEN + 1];
402char factory_sn_buf[PRODINFO_MAX_SSN_LEN + 1];
403char AdbEnable[MAX_RSP_SIZE];
404#endif
405#if defined(ENABLE_PRODINFO_ACCESS)
406char sn_buf[PRODINFO_MAX_ISN_LEN + 1];
407#else
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800408char sn_buf[13];
tracychui9d60fc52020-06-05 17:31:38 +0800409#endif
Dhaval Patel223ec952013-07-18 14:49:44 -0700410char display_panel_buf[MAX_PANEL_BUF_SIZE];
Unnati Gandhi62c8ab82014-01-24 11:01:01 +0530411char panel_display_mode[MAX_RSP_SIZE];
Mayank Grovera64dfbe2018-05-17 14:06:34 +0530412char soc_version_str[MAX_RSP_SIZE];
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530413char block_size_string[MAX_RSP_SIZE];
Rahul Shaharee7baede2021-02-02 13:23:57 +0530414static char SnapshotMergeState[MAX_RSP_SIZE];
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +0530415#if PRODUCT_IOT
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530416
417/* For IOT we are using custom version */
418#define PRODUCT_IOT_VERSION "IOT001"
419char bootloader_version_string[MAX_RSP_SIZE];
420#endif
lijuang102dfa92015-10-09 18:31:03 +0800421
422#if CHECK_BAT_VOLTAGE
lijuang65c5a822015-08-29 16:35:36 +0800423char battery_voltage[MAX_RSP_SIZE];
lijuang102dfa92015-10-09 18:31:03 +0800424char battery_soc_ok [MAX_RSP_SIZE];
425#endif
426
lijuangf16461c2015-08-03 17:09:34 +0800427char get_variant[MAX_RSP_SIZE];
Greg Griscod6250552011-06-29 14:40:23 -0700428
Greg Griscod2471ef2011-07-14 13:00:42 -0700429extern int emmc_recovery_init(void);
430
Kinson Chik0b1c8162011-08-31 16:31:57 -0700431#if NO_KEYPAD_DRIVER
432extern int fastboot_trigger(void);
433#endif
Greg Griscod2471ef2011-07-14 13:00:42 -0700434
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530435static void update_ker_tags_rdisk_addr(boot_img_hdr *hdr, bool is_arm64)
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700436{
437 /* overwrite the destination of specified for the project */
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700438#ifdef ABOOT_IGNORE_BOOT_HEADER_ADDRS
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800439 if (is_arm64)
440 hdr->kernel_addr = ABOOT_FORCE_KERNEL64_ADDR;
441 else
442 hdr->kernel_addr = ABOOT_FORCE_KERNEL_ADDR;
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700443 hdr->ramdisk_addr = ABOOT_FORCE_RAMDISK_ADDR;
444 hdr->tags_addr = ABOOT_FORCE_TAGS_ADDR;
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700445#endif
446}
447
Dima Zavin42168f22009-01-30 11:52:22 -0800448static void ptentry_to_tag(unsigned **ptr, struct ptentry *ptn)
449{
450 struct atag_ptbl_entry atag_ptn;
451
452 memcpy(atag_ptn.name, ptn->name, 16);
453 atag_ptn.name[15] = '\0';
454 atag_ptn.offset = ptn->start;
455 atag_ptn.size = ptn->length;
456 atag_ptn.flags = ptn->flags;
457 memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry));
458 *ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned);
459}
Mayank Grover9df84c02018-08-30 15:46:35 +0530460#ifdef VERIFIED_BOOT_2
461void load_vbmeta_image(void **vbmeta_image_buf, uint32_t *vbmeta_image_sz)
462{
463 int index = 0;
464 char *vbm_img_buf = NULL;
465 unsigned long long ptn = 0;
466 unsigned long long ptn_size = 0;
467
468 /* Immediately return if dtbo is not supported */
469 index = partition_get_index("vbmeta");
470 ptn = partition_get_offset(index);
471 if(!ptn)
472 {
473 dprintf(CRITICAL, "ERROR: vbmeta partition not found.\n");
474 return;
475 }
476
477 ptn_size = partition_get_size(index);
478 if (ptn_size > MAX_SUPPORTED_VBMETA_IMG_BUF)
479 {
480 dprintf(CRITICAL, "ERROR: vbmeta parition size is greater than supported.\n");
481 return;
482 }
483
484 vbm_img_buf = (char *)memalign(CACHE_LINE, ROUNDUP((uint32_t)ptn_size, CACHE_LINE));
485 if (!vbm_img_buf)
486 {
487 dprintf(CRITICAL, "ERROR: vbmeta unable to locate buffer\n");
488 return;
489 }
490
491 mmc_set_lun(partition_get_lun(index));
492 if (mmc_read(ptn, (uint32_t *)vbm_img_buf, (uint32_t)ptn_size))
493 {
494 dprintf(CRITICAL, "ERROR: vbmeta read failure\n");
495 free(vbm_img_buf);
496 return;
497 }
498
499 *vbmeta_image_buf = vbm_img_buf;
500 *vbmeta_image_sz = (uint32_t)ptn_size;
501 return;
502}
503#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -0800504
lijuang102dfa92015-10-09 18:31:03 +0800505#if CHECK_BAT_VOLTAGE
506void update_battery_status(void)
507{
508 snprintf(battery_voltage,MAX_RSP_SIZE, "%d",target_get_battery_voltage());
509 snprintf(battery_soc_ok ,MAX_RSP_SIZE, "%s",target_battery_soc_ok()? "yes":"no");
510}
511#endif
512
michaellin6be1f392020-04-24 15:05:10 +0800513uint32_t GetPcbaVariant(void)
514{
515 uint8_t GPIO_97=10;
516 uint8_t GPIO_98=10;
517 uint8_t GPIO_99=10;
518
519 uint8_t pcba_stage = 0;
520
521 // Config GPIO
522 gpio_tlmm_config(97, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_ENABLE);
523 gpio_tlmm_config(98, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_ENABLE);
524 gpio_tlmm_config(99, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_ENABLE);
525
526 /* Wait for the gpio config to take effect - debounce time */
527 thread_sleep(10);
528
529 /* Get status of GPIO */
530 GPIO_97 = gpio_status(97);
531 GPIO_98 = gpio_status(98);
532 GPIO_99 = gpio_status(99);
533
534 pcba_stage = (GPIO_99 << 2) + (GPIO_98 << 1) + GPIO_97;
535 dprintf(ALWAYS, "pcba_stage status: %u\n", pcba_stage);
536 // GPIO_99 GPIO_98 GPIO_97
537 // 0 0 0 EP0
538 // 0 0 1 EP1
539 // 0 1 0 EP2
540 // 0 1 1 PP
michaellinaf8857a2020-05-05 14:58:47 +0800541 // 0 1 1 FP(8901MB-007)/PP
542 // 1 0 0 MP(8901MB-008)
543 // 1 0 1 MP-8903MB_001
michaellin6be1f392020-04-24 15:05:10 +0800544 return pcba_stage;
545}
546
tedwub36be742020-07-03 18:02:48 +0800547uint32_t get_rf_variant(void)
548{
549 static uint32_t rf_id = 0xFF;
550
551 if (0xFF == rf_id) {
552 rf_id = (gpio_status(RF_VARIANT_PIN_1) << 1) + gpio_status(RF_VARIANT_PIN_0);
553 }
554 dprintf(CRITICAL, "RF Variant ID: %d\n", rf_id);
555
556 return rf_id;
557}
558
Neeti Desaie245d492012-06-01 12:52:13 -0700559unsigned char *update_cmdline(const char * cmdline)
Brian Swetland9c4c0752009-01-25 16:23:50 -0800560{
David Ng183a7422009-12-07 14:55:21 -0800561 int cmdline_len = 0;
562 int have_cmdline = 0;
Amol Jadi168b7712012-03-06 16:15:00 -0800563 unsigned char *cmdline_final = NULL;
Neeti Desaie245d492012-06-01 12:52:13 -0700564 int pause_at_bootup = 0;
tracychui9d60fc52020-06-05 17:31:38 +0800565#if defined(ENABLE_PRODINFO_ACCESS)
566 int AdbEnable = 0;
567#endif
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800568 bool warm_boot = false;
Pavel Nedev5614d222013-06-17 18:01:02 +0300569 bool gpt_exists = partition_gpt_exists();
Joonwoo Park61112782013-10-02 19:50:39 -0700570 int have_target_boot_params = 0;
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700571 char *boot_dev_buf = NULL;
Monika Singh292b3e92018-03-17 22:40:23 +0530572#ifdef MDTP_SUPPORT
Mayank Grover351a75e2017-05-30 20:06:08 +0530573 bool is_mdtp_activated = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530574#endif
Mayank Grover351a75e2017-05-30 20:06:08 +0530575 int current_active_slot = INVALID;
Mayank Grover3804be72017-06-22 11:59:23 +0530576 int system_ptn_index = -1;
577 unsigned int lun = 0;
578 char lun_char_base = 'a';
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530579#if VERITY_LE
580 int syspath_buflen = strlen(verity_dev)
581 + strlen(verity_system_part) + (sizeof(char) * 2) + 2
582 + strlen(verity_params) + sizeof(int) + 2;
583#else
lijuang83ef4b22018-08-23 11:01:55 +0800584 int syspath_buflen = strlen(sys_path) + sizeof(int) + 2; /*allocate buflen for largest possible string*/
585 char dtbo_idx_str[MAX_DTBO_IDX_STR] = "\0";
586 int dtbo_idx = INVALID_PTN;
Parth Dixit1375d9e2019-07-08 20:56:13 +0530587 char dtb_idx_str[MAX_DTB_IDX_STR] = "\0";
588 int dtb_idx = INVALID_PTN;
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530589#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530590 char syspath_buf[syspath_buflen];
Mayank Grover466d6562018-05-10 14:52:20 +0530591#if HIBERNATION_SUPPORT
592 int resume_buflen = strlen(resume) + sizeof(int) + 2;
593 char resume_buf[resume_buflen];
594 int swap_ptn_index = INVALID_PTN;
595#endif
596
Mayank Grover889be1b2017-09-12 20:12:23 +0530597#if VERIFIED_BOOT
598 uint32_t boot_state = RED;
599#endif
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530600
tedwub36be742020-07-03 18:02:48 +0800601 const char *pRFvar[4] = {rfvar_0, rfvar_1, rfvar_2, rfvar_3};
602
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530603#if USE_LE_SYSTEMD
604 is_systemd_present=true;
605#endif
606
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700607#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530608 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +0530609 {
610 boot_state = boot_verify_get_state();
611 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530612#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700613
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200614#ifdef MDTP_SUPPORT
615 mdtp_activated(&is_mdtp_activated);
616#endif /* MDTP_SUPPORT */
Dima Zavin42168f22009-01-30 11:52:22 -0800617
Brian Swetland9c4c0752009-01-25 16:23:50 -0800618 if (cmdline && cmdline[0]) {
David Ng183a7422009-12-07 14:55:21 -0800619 cmdline_len = strlen(cmdline);
620 have_cmdline = 1;
621 }
622 if (target_is_emmc_boot()) {
623 cmdline_len += strlen(emmc_cmdline);
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700624 boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN);
Mayank Groverb716edf2019-05-08 16:06:55 +0530625 if (!boot_dev_buf) {
626 dprintf(CRITICAL, "ERROR: Failed to allocate boot_dev_buf\n");
627 } else {
lijuangd28587b2021-04-27 15:54:05 +0800628 platform_boot_dev_cmdline(boot_dev_buf, sizeof(char) * BOOT_DEV_MAX_LEN);
Mayank Groverb716edf2019-05-08 16:06:55 +0530629#if USE_BOOTDEV_CMDLINE
630 cmdline_len += strlen(boot_dev_buf);
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700631#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530632 if (target_dynamic_partition_supported()) {
633 cmdline_len += strlen(dynamic_bootdev_cmdline);
634 cmdline_len += strlen(boot_dev_buf);
635 }
636 }
David Ng183a7422009-12-07 14:55:21 -0800637 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800638
639 cmdline_len += strlen(usb_sn_cmdline);
640 cmdline_len += strlen(sn_buf);
tracychui9d60fc52020-06-05 17:31:38 +0800641#if defined(ENABLE_PRODINFO_ACCESS)
642 cmdline_len += strlen(cust_sn_cmdline);
643 cmdline_len += strlen(cust_sn_buf);
644 cmdline_len += strlen(factory_sn_cmdline);
645 cmdline_len += strlen(factory_sn_buf);
646#endif
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800647
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700648#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530649 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700650 {
Mayank Grover889be1b2017-09-12 20:12:23 +0530651 cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
652 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
653 {
654 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
655 ASSERT(0);
656 }
657 cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
658 cmdline_len += strlen(keymaster_v1);
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700659 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530660#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700661
Monika Singh292b3e92018-03-17 22:40:23 +0530662
663 if (vbcmdline != NULL) {
664 dprintf(DEBUG, "UpdateCmdLine vbcmdline present len %d\n",
665 strlen(vbcmdline));
666 cmdline_len += strlen(vbcmdline);
667 }
668
Pavel Nedev5614d222013-06-17 18:01:02 +0300669 if (boot_into_recovery && gpt_exists)
670 cmdline_len += strlen(secondary_gpt_enable);
671
Monika Singh292b3e92018-03-17 22:40:23 +0530672#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200673 if(is_mdtp_activated)
674 cmdline_len += strlen(mdtp_activated_flag);
Monika Singh292b3e92018-03-17 22:40:23 +0530675#endif
Pavel Nedev328ac822013-04-05 15:25:11 +0300676 if (boot_into_ffbm) {
677 cmdline_len += strlen(androidboot_mode);
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530678
679 if(is_systemd_present)
680 cmdline_len += strlen(systemd_ffbm_mode);
681
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700682 cmdline_len += strlen(ffbm_mode_string);
Pavel Nedev898298c2013-02-27 12:36:09 -0800683 /* reduce kernel console messages to speed-up boot */
684 cmdline_len += strlen(loglevel);
Matthew Qind886f3c2014-01-17 16:52:01 +0800685 } else if (boot_reason_alarm) {
686 cmdline_len += strlen(alarmboot_cmdline);
Zhenhua Huang431dafa2015-06-30 16:13:37 +0800687 } else if ((target_build_variant_user() || device.charger_screen_enabled)
lijuang266b17d2018-08-17 18:53:42 +0800688 && target_pause_for_battery_charge() && !boot_into_recovery) {
David Ngf773dde2010-07-26 19:55:08 -0700689 pause_at_bootup = 1;
690 cmdline_len += strlen(battchg_pause);
691 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800692
tracychui9d60fc52020-06-05 17:31:38 +0800693#if defined(ENABLE_PRODINFO_ACCESS)
694 if (prod.is_adb_enabled) {
695 dprintf(CRITICAL, "Device will enable adb\n");
696
697 prod.is_adb_enabled = 0;
698 write_prod_info(&prod);
699
700 AdbEnable = 1;
701 cmdline_len += strlen(UsbAdbEnable);
702 }
703#endif
704
Shashank Mittalcd98d472011-08-02 14:29:24 -0700705 if(target_use_signed_kernel() && auth_kernel_img) {
706 cmdline_len += strlen(auth_kernel);
707 }
708
Joonwoo Park61112782013-10-02 19:50:39 -0700709 if (get_target_boot_params(cmdline, boot_into_recovery ? "recoveryfs" :
710 "system",
vijay kumar870515d2015-08-31 16:37:24 +0530711 &target_boot_params) == 0) {
Joonwoo Park61112782013-10-02 19:50:39 -0700712 have_target_boot_params = 1;
713 cmdline_len += strlen(target_boot_params);
714 }
715
Ajay Dudanid04110c2011-01-17 23:55:07 -0800716 /* Determine correct androidboot.baseband to use */
717 switch(target_baseband())
718 {
719 case BASEBAND_APQ:
720 cmdline_len += strlen(baseband_apq);
721 break;
722
723 case BASEBAND_MSM:
724 cmdline_len += strlen(baseband_msm);
725 break;
726
727 case BASEBAND_CSFB:
728 cmdline_len += strlen(baseband_csfb);
729 break;
730
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800731 case BASEBAND_SVLTE2A:
732 cmdline_len += strlen(baseband_svlte2a);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800733 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700734
735 case BASEBAND_MDM:
736 cmdline_len += strlen(baseband_mdm);
737 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700738
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800739 case BASEBAND_MDM2:
740 cmdline_len += strlen(baseband_mdm2);
741 break;
742
Amol Jadi5c61a952012-05-04 17:05:35 -0700743 case BASEBAND_SGLTE:
744 cmdline_len += strlen(baseband_sglte);
745 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530746
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800747 case BASEBAND_SGLTE2:
748 cmdline_len += strlen(baseband_sglte2);
749 break;
750
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530751 case BASEBAND_DSDA:
752 cmdline_len += strlen(baseband_dsda);
753 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800754
755 case BASEBAND_DSDA2:
756 cmdline_len += strlen(baseband_dsda2);
757 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530758 case BASEBAND_APQ_NOWGR:
759 cmdline_len += strlen(baseband_apq_nowgr);
760 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800761 }
762
michaellin6be1f392020-04-24 15:05:10 +0800763 switch(GetPcbaVariant())
764 {
765 case 0: // EP0
766 cmdline_len += strlen(PCBA_STAGE_0);
767 break;
768
769 case 1: // EP1
770 cmdline_len += strlen(PCBA_STAGE_1);
771 break;
772
773 case 2: // EP2
774 cmdline_len += strlen(PCBA_STAGE_2);
775 break;
776
michaellinaf8857a2020-05-05 14:58:47 +0800777 case 3: // FP(8901MB-007)/PP
michaellin6be1f392020-04-24 15:05:10 +0800778 cmdline_len += strlen(PCBA_STAGE_3);
779 break;
780
michaellinaf8857a2020-05-05 14:58:47 +0800781 case 4: // MP(8901MB-008)
michaellin6be1f392020-04-24 15:05:10 +0800782 cmdline_len += strlen(PCBA_STAGE_4);
783 break;
784
michaellinaf8857a2020-05-05 14:58:47 +0800785 case 5: // MP-8903MB_001
786 cmdline_len += strlen(PCBA_STAGE_5);
787 break;
788
michaellin6be1f392020-04-24 15:05:10 +0800789 default:// Reserved
790 cmdline_len += strlen(PCBA_STAGE_F);
791 break;
792 }
793
tedwub36be742020-07-03 18:02:48 +0800794 cmdline_len += strlen(rfvar_prefix);
795 cmdline_len += strlen(pRFvar[get_rf_variant()]);
796
tracychui792d2ad2020-06-15 10:50:49 +0800797 if(smem_get_ddr_size() == MEM_3GB )
798 {
799 cmdline_len += strlen(memory_config_3G);
800 }
801 else
802 {
803 cmdline_len += strlen(memory_config_4G);
804 }
805
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300806#if ENABLE_DISPLAY
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800807 if (cmdline) {
808 if ((strstr(cmdline, DISPLAY_DEFAULT_PREFIX) == NULL) &&
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530809 target_display_panel_node(display_panel_buf,
810 MAX_PANEL_BUF_SIZE) &&
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800811 strlen(display_panel_buf)) {
812 cmdline_len += strlen(display_panel_buf);
813 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700814 }
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300815#endif
Dhaval Patel223ec952013-07-18 14:49:44 -0700816
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800817 if (target_warm_boot()) {
818 warm_boot = true;
819 cmdline_len += strlen(warmboot_cmdline);
820 }
821
Mayank Grover5384ed82018-05-09 12:09:24 +0530822 if (target_uses_system_as_root() ||
823 partition_multislot_is_supported())
Mayank Grover351a75e2017-05-30 20:06:08 +0530824 {
825 current_active_slot = partition_find_active_slot();
826 cmdline_len += (strlen(androidboot_slot_suffix)+
827 strlen(SUFFIX_SLOT(current_active_slot)));
828
Mayank Grover3804be72017-06-22 11:59:23 +0530829 system_ptn_index = partition_get_index("system");
830 if (platform_boot_dev_isemmc())
831 {
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530832#if VERITY_LE
833 /*
834 Condition 4: Verity and A/B both enabled
835 Eventual command line looks like:
836 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
837 ... root=/dev/dm-0 dm="system_<slot_suffix> none ro,0 1 android-verity /dev/mmcblk0p<NN>"
838 */
839 snprintf(syspath_buf, syspath_buflen, " %s %s%s %s%d\"",
840 verity_dev,
841 verity_system_part, suffix_slot[current_active_slot],
842 verity_params, system_ptn_index + 1);
843#else
844 /*
845 Condition 5: A/B enabled, but verity disabled
846 Eventual command line looks like:
847 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
848 ... root=/dev/mmcblk0p<NN> ...
849 */
850 snprintf(syspath_buf, syspath_buflen, " %s%d",
851 sys_path, system_ptn_index + 1);
852#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530853 }
854 else
855 {
856 lun = partition_get_lun(system_ptn_index);
857 snprintf(syspath_buf, syspath_buflen, " root=/dev/sd%c%d",
858 lun_char_base + lun,
859 partition_get_index_in_lun("system", lun));
860 }
Mayank Grover351a75e2017-05-30 20:06:08 +0530861
Monika Singh292b3e92018-03-17 22:40:23 +0530862#ifndef VERIFIED_BOOT_2
Mayank Grover3804be72017-06-22 11:59:23 +0530863 cmdline_len += strlen(syspath_buf);
Monika Singh292b3e92018-03-17 22:40:23 +0530864#endif
Mayank Grover5384ed82018-05-09 12:09:24 +0530865 }
866
867 if (target_uses_system_as_root() ||
868 partition_multislot_is_supported())
869 {
870 cmdline_len += strlen(sys_path_cmdline);
Mayank Groverb716edf2019-05-08 16:06:55 +0530871
872 /* For dynamic partition, support skip skip_initramfs */
873 if (!target_dynamic_partition_supported() &&
874 !boot_into_recovery)
Mayank Grover351a75e2017-05-30 20:06:08 +0530875 cmdline_len += strlen(skip_ramfs);
876 }
877
Mayank Grover466d6562018-05-10 14:52:20 +0530878#if HIBERNATION_SUPPORT
879 if (platform_boot_dev_isemmc())
880 {
881 swap_ptn_index = partition_get_index("swap");
882 if (swap_ptn_index != INVALID_PTN)
883 {
884 snprintf(resume_buf, resume_buflen,
885 " %s%d", resume,
886 (swap_ptn_index + 1));
887 cmdline_len += strlen(resume_buf);
888 }
889 else
890 {
891 dprintf(INFO, "WARNING: swap partition not found\n");
892 }
893 }
894#endif
895
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800896#if TARGET_CMDLINE_SUPPORT
897 char *target_cmdline_buf = malloc(TARGET_MAX_CMDLNBUF);
898 int target_cmd_line_len;
899 ASSERT(target_cmdline_buf);
900 target_cmd_line_len = target_update_cmdline(target_cmdline_buf);
901 cmdline_len += target_cmd_line_len;
902#endif
903
lijuang83ef4b22018-08-23 11:01:55 +0800904#if !VERITY_LE
905 dtbo_idx = get_dtbo_idx ();
906 if (dtbo_idx != INVALID_PTN) {
907 snprintf(dtbo_idx_str, sizeof(dtbo_idx_str), "%s%d",
908 android_boot_dtbo_idx, dtbo_idx);
909 cmdline_len += strlen (dtbo_idx_str);
910 }
Parth Dixit1375d9e2019-07-08 20:56:13 +0530911
912 dtb_idx = get_dtb_idx ();
913 if (dtb_idx != INVALID_PTN) {
914 snprintf(dtb_idx_str, sizeof(dtb_idx_str), "%s%d",
915 android_boot_dtb_idx, dtb_idx);
916 cmdline_len += strlen (dtb_idx_str);
917 }
lijuang83ef4b22018-08-23 11:01:55 +0800918#endif
919
jhchena8a15dd2020-04-24 15:45:57 +0800920#ifdef ENABLE_FUSE_CHECK
921 {
922 int hw_key_status = readl(0xA01D0);
923 is_fused = (hw_key_status & 0x2) >> 1;
924 dprintf(CRITICAL, "hw_key_status = 0x%x, is_fused=%d\n", hw_key_status, is_fused);
925 if (is_fused) {
926 cmdline_len += strlen(fuse_blown);
927 } else {
928 cmdline_len += strlen(fuse_not_blown);
929 }
930 }
931#endif
932
David Ng183a7422009-12-07 14:55:21 -0800933 if (cmdline_len > 0) {
934 const char *src;
Maria Yu52254c02014-07-04 16:14:54 +0800935 unsigned char *dst;
936
937 cmdline_final = (unsigned char*) malloc((cmdline_len + 4) & (~3));
938 ASSERT(cmdline_final != NULL);
vijay kumar287bb542015-09-29 13:01:52 +0530939 memset((void *)cmdline_final, 0, sizeof(*cmdline_final));
Maria Yu52254c02014-07-04 16:14:54 +0800940 dst = cmdline_final;
Neeti Desaie245d492012-06-01 12:52:13 -0700941
Amol Jadi168b7712012-03-06 16:15:00 -0800942 /* Save start ptr for debug print */
David Ng183a7422009-12-07 14:55:21 -0800943 if (have_cmdline) {
944 src = cmdline;
945 while ((*dst++ = *src++));
946 }
947 if (target_is_emmc_boot()) {
948 src = emmc_cmdline;
949 if (have_cmdline) --dst;
David Ngf773dde2010-07-26 19:55:08 -0700950 have_cmdline = 1;
951 while ((*dst++ = *src++));
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800952#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700953 src = boot_dev_buf;
Mayank Groverb716edf2019-05-08 16:06:55 +0530954 if (have_cmdline &&
955 boot_dev_buf) {
956 --dst;
957 while ((*dst++ = *src++));
958 }
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700959#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530960 /* Dynamic partition append boot_devices */
961 if (target_dynamic_partition_supported() &&
962 boot_dev_buf) {
963 src = dynamic_bootdev_cmdline;
964 if (have_cmdline) --dst;
965 while ((*dst++ = *src++));
966 src = boot_dev_buf;
967 if (have_cmdline) --dst;
968 while ((*dst++ = *src++));
969 }
David Ngf773dde2010-07-26 19:55:08 -0700970 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800971
michaellin6be1f392020-04-24 15:05:10 +0800972 switch(GetPcbaVariant())
973 {
974 case 0:
975 src = PCBA_STAGE_0;
976 if (have_cmdline) --dst;
977 while ((*dst++ = *src++));
978 break;
979 case 1:
980 src = PCBA_STAGE_1;
981 if (have_cmdline) --dst;
982 while ((*dst++ = *src++));
983 break;
984 case 2:
985 src = PCBA_STAGE_2;
986 if (have_cmdline) --dst;
987 while ((*dst++ = *src++));
988 break;
989 case 3:
990 src = PCBA_STAGE_3;
991 if (have_cmdline) --dst;
992 while ((*dst++ = *src++));
993 break;
994 case 4:
995 src = PCBA_STAGE_4;
996 if (have_cmdline) --dst;
997 while ((*dst++ = *src++));
998 break;
michaellinaf8857a2020-05-05 14:58:47 +0800999 case 5:
1000 src = PCBA_STAGE_5;
1001 if (have_cmdline) --dst;
1002 while ((*dst++ = *src++));
1003 break;
michaellin6be1f392020-04-24 15:05:10 +08001004 default:
1005 src = PCBA_STAGE_F;
1006 if (have_cmdline) --dst;
1007 while ((*dst++ = *src++));
1008 break;
1009 }
tedwub36be742020-07-03 18:02:48 +08001010 src = rfvar_prefix;
1011 if (have_cmdline) --dst;
1012 while ((*dst++ = *src++));
1013 src = pRFvar[get_rf_variant()];
1014 if (have_cmdline) --dst;
1015 while ((*dst++ = *src++));
1016
tracychui792d2ad2020-06-15 10:50:49 +08001017 if(smem_get_ddr_size() == MEM_3GB )
1018 {
1019 src = memory_config_3G;
1020 if (have_cmdline) --dst;
1021 while ((*dst++ = *src++));
1022 }
1023 else
1024 {
1025 src = memory_config_4G;
1026 if (have_cmdline) --dst;
1027 while ((*dst++ = *src++));
1028 }
michaellin6be1f392020-04-24 15:05:10 +08001029
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -07001030#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +05301031 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -07001032 {
Mayank Grover889be1b2017-09-12 20:12:23 +05301033 src = verified_state;
1034 if(have_cmdline) --dst;
1035 have_cmdline = 1;
1036 while ((*dst++ = *src++));
1037 src = vbsn[boot_state].name;
1038 if(have_cmdline) --dst;
1039 while ((*dst++ = *src++));
1040
1041 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
1042 {
1043 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
1044 ASSERT(0);
1045 }
1046 src = verity_mode;
1047 if(have_cmdline) --dst;
1048 while ((*dst++ = *src++));
1049 src = vbvm[device.verity_mode].name;
1050 if(have_cmdline) -- dst;
1051 while ((*dst++ = *src++));
1052 src = keymaster_v1;
1053 if(have_cmdline) --dst;
1054 while ((*dst++ = *src++));
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -07001055 }
Parth Dixitddbc7352015-10-18 03:13:31 +05301056#endif
Monika Singh292b3e92018-03-17 22:40:23 +05301057
1058 if (vbcmdline != NULL) {
1059 src = vbcmdline;
1060 if (have_cmdline) --dst;
1061 while ((*dst++ = *src++));
1062 }
1063
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08001064 src = usb_sn_cmdline;
1065 if (have_cmdline) --dst;
1066 have_cmdline = 1;
1067 while ((*dst++ = *src++));
1068 src = sn_buf;
1069 if (have_cmdline) --dst;
1070 have_cmdline = 1;
1071 while ((*dst++ = *src++));
tracychui9d60fc52020-06-05 17:31:38 +08001072
1073 #if defined(ENABLE_PRODINFO_ACCESS)
1074 src = cust_sn_cmdline;
1075 if (have_cmdline) --dst;
1076 have_cmdline = 1;
1077 while ((*dst++ = *src++));
1078 src = cust_sn_buf;
1079 if (have_cmdline) --dst;
1080 have_cmdline = 1;
1081 while ((*dst++ = *src++));
1082 src = factory_sn_cmdline;
1083 if (have_cmdline) --dst;
1084 have_cmdline = 1;
1085 while ((*dst++ = *src++));
1086 src = factory_sn_buf;
1087 if (have_cmdline) --dst;
1088 have_cmdline = 1;
1089 while ((*dst++ = *src++));
1090 #endif
Hanumant Singh8e1ac232014-01-29 13:41:51 -08001091 if (warm_boot) {
1092 if (have_cmdline) --dst;
1093 src = warmboot_cmdline;
1094 while ((*dst++ = *src++));
1095 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08001096
Pavel Nedev5614d222013-06-17 18:01:02 +03001097 if (boot_into_recovery && gpt_exists) {
1098 src = secondary_gpt_enable;
1099 if (have_cmdline) --dst;
1100 while ((*dst++ = *src++));
1101 }
Monika Singh292b3e92018-03-17 22:40:23 +05301102#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +02001103 if (is_mdtp_activated) {
1104 src = mdtp_activated_flag;
1105 if (have_cmdline) --dst;
1106 while ((*dst++ = *src++));
1107 }
Monika Singh292b3e92018-03-17 22:40:23 +05301108#endif
Pavel Nedev328ac822013-04-05 15:25:11 +03001109 if (boot_into_ffbm) {
1110 src = androidboot_mode;
1111 if (have_cmdline) --dst;
1112 while ((*dst++ = *src++));
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001113 src = ffbm_mode_string;
Pavel Nedev328ac822013-04-05 15:25:11 +03001114 if (have_cmdline) --dst;
1115 while ((*dst++ = *src++));
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +05301116
1117 if(is_systemd_present) {
1118 src = systemd_ffbm_mode;
1119 if (have_cmdline) --dst;
1120 while ((*dst++ = *src++));
1121 }
1122
Pavel Nedev898298c2013-02-27 12:36:09 -08001123 src = loglevel;
1124 if (have_cmdline) --dst;
1125 while ((*dst++ = *src++));
Matthew Qind886f3c2014-01-17 16:52:01 +08001126 } else if (boot_reason_alarm) {
1127 src = alarmboot_cmdline;
1128 if (have_cmdline) --dst;
1129 while ((*dst++ = *src++));
Pavel Nedev328ac822013-04-05 15:25:11 +03001130 } else if (pause_at_bootup) {
David Ngf773dde2010-07-26 19:55:08 -07001131 src = battchg_pause;
1132 if (have_cmdline) --dst;
David Ng183a7422009-12-07 14:55:21 -08001133 while ((*dst++ = *src++));
1134 }
Ajay Dudanid04110c2011-01-17 23:55:07 -08001135
tracychui9d60fc52020-06-05 17:31:38 +08001136#if defined(ENABLE_PRODINFO_ACCESS)
1137 if (AdbEnable) {
1138 src = UsbAdbEnable;
1139 if (have_cmdline) --dst;
1140 while ((*dst++ = *src++));
1141 }
1142#endif
1143
Shashank Mittalcd98d472011-08-02 14:29:24 -07001144 if(target_use_signed_kernel() && auth_kernel_img) {
1145 src = auth_kernel;
1146 if (have_cmdline) --dst;
1147 while ((*dst++ = *src++));
1148 }
1149
Ajay Dudanid04110c2011-01-17 23:55:07 -08001150 switch(target_baseband())
1151 {
1152 case BASEBAND_APQ:
1153 src = baseband_apq;
1154 if (have_cmdline) --dst;
1155 while ((*dst++ = *src++));
1156 break;
1157
1158 case BASEBAND_MSM:
1159 src = baseband_msm;
1160 if (have_cmdline) --dst;
1161 while ((*dst++ = *src++));
1162 break;
1163
1164 case BASEBAND_CSFB:
1165 src = baseband_csfb;
1166 if (have_cmdline) --dst;
1167 while ((*dst++ = *src++));
1168 break;
1169
Ajay Dudani6cff85e2011-02-04 16:02:16 -08001170 case BASEBAND_SVLTE2A:
1171 src = baseband_svlte2a;
Ajay Dudanid04110c2011-01-17 23:55:07 -08001172 if (have_cmdline) --dst;
1173 while ((*dst++ = *src++));
1174 break;
Ajay Dudani403bc492011-09-30 16:17:21 -07001175
1176 case BASEBAND_MDM:
1177 src = baseband_mdm;
1178 if (have_cmdline) --dst;
1179 while ((*dst++ = *src++));
1180 break;
Amol Jadi5c61a952012-05-04 17:05:35 -07001181
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -08001182 case BASEBAND_MDM2:
1183 src = baseband_mdm2;
1184 if (have_cmdline) --dst;
1185 while ((*dst++ = *src++));
1186 break;
1187
Amol Jadi5c61a952012-05-04 17:05:35 -07001188 case BASEBAND_SGLTE:
1189 src = baseband_sglte;
1190 if (have_cmdline) --dst;
1191 while ((*dst++ = *src++));
1192 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +05301193
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -08001194 case BASEBAND_SGLTE2:
1195 src = baseband_sglte2;
1196 if (have_cmdline) --dst;
1197 while ((*dst++ = *src++));
1198 break;
1199
Channagoud Kadabi141f2982012-10-31 11:23:02 +05301200 case BASEBAND_DSDA:
1201 src = baseband_dsda;
1202 if (have_cmdline) --dst;
1203 while ((*dst++ = *src++));
1204 break;
Amol Jadi2a15a272013-01-22 12:03:36 -08001205
1206 case BASEBAND_DSDA2:
1207 src = baseband_dsda2;
1208 if (have_cmdline) --dst;
1209 while ((*dst++ = *src++));
1210 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +05301211 case BASEBAND_APQ_NOWGR:
1212 src = baseband_apq_nowgr;
1213 if (have_cmdline) --dst;
1214 while ((*dst++ = *src++));
1215 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -08001216 }
Dhaval Patel223ec952013-07-18 14:49:44 -07001217
1218 if (strlen(display_panel_buf)) {
Dhaval Patel223ec952013-07-18 14:49:44 -07001219 src = display_panel_buf;
1220 if (have_cmdline) --dst;
1221 while ((*dst++ = *src++));
1222 }
Joonwoo Park61112782013-10-02 19:50:39 -07001223
1224 if (have_target_boot_params) {
1225 if (have_cmdline) --dst;
1226 src = target_boot_params;
1227 while ((*dst++ = *src++));
vijay kumar870515d2015-08-31 16:37:24 +05301228 free(target_boot_params);
Joonwoo Park61112782013-10-02 19:50:39 -07001229 }
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -08001230
Mayank Grover351a75e2017-05-30 20:06:08 +05301231 if (partition_multislot_is_supported() && have_cmdline)
1232 {
1233 src = androidboot_slot_suffix;
1234 --dst;
1235 while ((*dst++ = *src++));
1236 --dst;
1237 src = SUFFIX_SLOT(current_active_slot);
1238 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +05301239 }
Mayank Grover351a75e2017-05-30 20:06:08 +05301240
Mayank Grover351a75e2017-05-30 20:06:08 +05301241
Mayank Grover5384ed82018-05-09 12:09:24 +05301242 /*
1243 * System-As-Root behaviour, system.img should contain both
1244 * system content and ramdisk content, and should be mounted at
1245 * root(a/b).
1246 * Apending skip_ramfs for non a/b builds which use, system as root.
1247 */
1248 if ((target_uses_system_as_root() ||
1249 partition_multislot_is_supported()) &&
1250 have_cmdline)
1251 {
Mayank Groverb716edf2019-05-08 16:06:55 +05301252 if (!target_dynamic_partition_supported() &&
1253 !boot_into_recovery)
Mayank Grover5384ed82018-05-09 12:09:24 +05301254 {
1255 src = skip_ramfs;
Mayank Grover351a75e2017-05-30 20:06:08 +05301256 --dst;
1257 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +05301258 }
1259
1260 src = sys_path_cmdline;
1261 --dst;
1262 while ((*dst++ = *src++));
Mayank Grover3804be72017-06-22 11:59:23 +05301263
Monika Singh292b3e92018-03-17 22:40:23 +05301264#ifndef VERIFIED_BOOT_2
Mayank Grover5384ed82018-05-09 12:09:24 +05301265 src = syspath_buf;
1266 --dst;
1267 while ((*dst++ = *src++));
Monika Singh292b3e92018-03-17 22:40:23 +05301268#endif
Mayank Grover351a75e2017-05-30 20:06:08 +05301269 }
1270
Mayank Grover466d6562018-05-10 14:52:20 +05301271#if HIBERNATION_SUPPORT
1272 if (swap_ptn_index != INVALID_PTN)
1273 {
1274 src = resume_buf;
1275 --dst;
1276 while ((*dst++ = *src++));
1277 }
1278#endif
1279
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -08001280#if TARGET_CMDLINE_SUPPORT
1281 if (target_cmdline_buf && target_cmd_line_len)
1282 {
1283 if (have_cmdline) --dst;
1284 src = target_cmdline_buf;
1285 while((*dst++ = *src++));
1286 free(target_cmdline_buf);
1287 }
1288#endif
lijuang83ef4b22018-08-23 11:01:55 +08001289
1290#if !VERITY_LE
1291 if (dtbo_idx != INVALID_PTN) {
1292 src = dtbo_idx_str;
1293 --dst;
1294 while ((*dst++ = *src++));
1295 }
Parth Dixit1375d9e2019-07-08 20:56:13 +05301296
1297 if (dtb_idx != INVALID_PTN) {
1298 src = dtb_idx_str;
1299 --dst;
1300 while ((*dst++ = *src++));
1301 }
lijuang83ef4b22018-08-23 11:01:55 +08001302#endif
jhchena8a15dd2020-04-24 15:45:57 +08001303
1304#ifdef ENABLE_FUSE_CHECK
1305 if (is_fused) {
1306 src = fuse_blown;
1307 if (have_cmdline) --dst;
1308 while ((*dst++ = *src++));
1309 } else {
1310 src = fuse_not_blown;
1311 if (have_cmdline) --dst;
1312 while ((*dst++ = *src++));
1313 }
1314#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001315 }
Dhaval Patel223ec952013-07-18 14:49:44 -07001316
1317
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -07001318 if (boot_dev_buf)
1319 free(boot_dev_buf);
1320
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08001321 if (cmdline_final)
1322 dprintf(INFO, "cmdline: %s\n", cmdline_final);
1323 else
1324 dprintf(INFO, "cmdline is NULL\n");
Neeti Desaie245d492012-06-01 12:52:13 -07001325 return cmdline_final;
1326}
1327
1328unsigned *atag_core(unsigned *ptr)
1329{
1330 /* CORE */
1331 *ptr++ = 2;
1332 *ptr++ = 0x54410001;
1333
1334 return ptr;
1335
1336}
1337
1338unsigned *atag_ramdisk(unsigned *ptr, void *ramdisk,
1339 unsigned ramdisk_size)
1340{
1341 if (ramdisk_size) {
1342 *ptr++ = 4;
1343 *ptr++ = 0x54420005;
1344 *ptr++ = (unsigned)ramdisk;
1345 *ptr++ = ramdisk_size;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001346 }
1347
Neeti Desaie245d492012-06-01 12:52:13 -07001348 return ptr;
1349}
1350
1351unsigned *atag_ptable(unsigned **ptr_addr)
1352{
1353 int i;
1354 struct ptable *ptable;
1355
1356 if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001357 *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
1358 sizeof(unsigned)));
Neeti Desaie245d492012-06-01 12:52:13 -07001359 *(*ptr_addr)++ = 0x4d534d70;
1360 for (i = 0; i < ptable->count; ++i)
1361 ptentry_to_tag(ptr_addr, ptable_get(ptable, i));
1362 }
1363
1364 return (*ptr_addr);
1365}
1366
1367unsigned *atag_cmdline(unsigned *ptr, const char *cmdline)
1368{
1369 int cmdline_length = 0;
1370 int n;
Neeti Desaie245d492012-06-01 12:52:13 -07001371 char *dest;
1372
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001373 cmdline_length = strlen((const char*)cmdline);
Neeti Desaie245d492012-06-01 12:52:13 -07001374 n = (cmdline_length + 4) & (~3);
1375
1376 *ptr++ = (n / 4) + 2;
1377 *ptr++ = 0x54410009;
1378 dest = (char *) ptr;
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001379 while ((*dest++ = *cmdline++));
Neeti Desaie245d492012-06-01 12:52:13 -07001380 ptr += (n / 4);
1381
1382 return ptr;
1383}
1384
1385unsigned *atag_end(unsigned *ptr)
1386{
Brian Swetland9c4c0752009-01-25 16:23:50 -08001387 /* END */
1388 *ptr++ = 0;
1389 *ptr++ = 0;
1390
Neeti Desaie245d492012-06-01 12:52:13 -07001391 return ptr;
1392}
1393
1394void generate_atags(unsigned *ptr, const char *cmdline,
1395 void *ramdisk, unsigned ramdisk_size)
1396{
vijay kumar21a37452015-12-29 16:23:21 +05301397 unsigned *orig_ptr = ptr;
Neeti Desaie245d492012-06-01 12:52:13 -07001398 ptr = atag_core(ptr);
1399 ptr = atag_ramdisk(ptr, ramdisk, ramdisk_size);
1400 ptr = target_atag_mem(ptr);
1401
1402 /* Skip NAND partition ATAGS for eMMC boot */
1403 if (!target_is_emmc_boot()){
1404 ptr = atag_ptable(&ptr);
1405 }
1406
vijay kumar21a37452015-12-29 16:23:21 +05301407 /*
1408 * Atags size filled till + cmdline size + 1 unsigned for 4-byte boundary + 4 unsigned
1409 * for atag identifier in atag_cmdline and atag_end should be with in MAX_TAGS_SIZE bytes
1410 */
Mayank Groverbc8a2ef2018-02-23 18:03:36 +05301411 if (!cmdline)
1412 return;
1413
vijay kumar21a37452015-12-29 16:23:21 +05301414 if (((ptr - orig_ptr) + strlen(cmdline) + 5 * sizeof(unsigned)) < MAX_TAGS_SIZE) {
1415 ptr = atag_cmdline(ptr, cmdline);
1416 ptr = atag_end(ptr);
1417 }
1418 else {
1419 dprintf(CRITICAL,"Crossing ATAGs Max size allowed\n");
1420 ASSERT(0);
1421 }
Neeti Desaie245d492012-06-01 12:52:13 -07001422}
1423
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001424typedef void entry_func_ptr(unsigned, unsigned, unsigned*);
Neeti Desaie245d492012-06-01 12:52:13 -07001425void boot_linux(void *kernel, unsigned *tags,
1426 const char *cmdline, unsigned machtype,
1427 void *ramdisk, unsigned ramdisk_size)
1428{
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001429 unsigned char *final_cmdline;
Amol Jadib6be5c12012-11-14 13:39:51 -08001430#if DEVICE_TREE
Neeti Desai17379b82012-06-04 18:42:53 -07001431 int ret = 0;
Amol Jadib6be5c12012-11-14 13:39:51 -08001432#endif
1433
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001434 void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001435 uint32_t tags_phys = PA((addr_t)tags);
vijay kumar1a50a642015-11-16 12:41:15 +05301436 struct kernel64_hdr *kptr = ((struct kernel64_hdr*)(PA((addr_t)kernel)));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001437
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301438 ramdisk = (void *)PA((addr_t)ramdisk);
Neeti Desaie245d492012-06-01 12:52:13 -07001439
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001440 final_cmdline = update_cmdline((const char*)cmdline);
1441
Neeti Desai17379b82012-06-04 18:42:53 -07001442#if DEVICE_TREE
Amol Jadib6be5c12012-11-14 13:39:51 -08001443 dprintf(INFO, "Updating device tree: start\n");
1444
Neeti Desai17379b82012-06-04 18:42:53 -07001445 /* Update the Device Tree */
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301446 ret = update_device_tree((void *)tags,(const char *)final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001447 if(ret)
1448 {
1449 dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
1450 ASSERT(0);
1451 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001452 dprintf(INFO, "Updating device tree: done\n");
Neeti Desai17379b82012-06-04 18:42:53 -07001453#else
Neeti Desaie245d492012-06-01 12:52:13 -07001454 /* Generating the Atags */
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001455 generate_atags(tags, final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001456#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001457
Monika Singh0ec6db82019-07-18 16:57:58 +05301458#if VERIFIED_BOOT
Monika Singhb0db4b82018-09-26 12:18:02 +05301459 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05301460 {
1461 if (device.verity_mode == 0) {
lijuangbdd9bb42016-03-01 18:22:17 +08001462#if FBCON_DISPLAY_MSG
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001463#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05301464 display_bootverify_menu(DISPLAY_MENU_EIO);
1465 wait_for_users_action();
1466 if(!pwr_key_is_pressed)
1467 shutdown_device();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001468#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301469 display_bootverify_menu(DISPLAY_MENU_LOGGING);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001470#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301471 wait_for_users_action();
lijuangbdd9bb42016-03-01 18:22:17 +08001472#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301473 dprintf(CRITICAL,
1474 "The dm-verity is not started in enforcing mode.\nWait for 5 seconds before proceeding\n");
1475 mdelay(5000);
lijuangbdd9bb42016-03-01 18:22:17 +08001476#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301477 }
lijuangbdd9bb42016-03-01 18:22:17 +08001478 }
lijuangbdd9bb42016-03-01 18:22:17 +08001479#endif
1480
1481#if VERIFIED_BOOT
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001482 /* Write protect the device info */
Channagoud Kadabi3bd9d1e2015-05-05 16:18:20 -07001483 if (!boot_into_recovery && target_build_variant_user() && devinfo_present && mmc_write_protect("devinfo", 1))
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001484 {
1485 dprintf(INFO, "Failed to write protect dev info\n");
1486 ASSERT(0);
1487 }
1488#endif
1489
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001490 /* Turn off splash screen if enabled */
1491#if DISPLAY_SPLASH_SCREEN
1492 target_display_shutdown();
1493#endif
1494
Veera Sundaram Sankaran67ea0932015-09-25 10:09:30 -07001495 /* Perform target specific cleanup */
1496 target_uninit();
Monika Singh292b3e92018-03-17 22:40:23 +05301497 free_verified_boot_resource(&info);
1498 if (final_cmdline)
1499 free(final_cmdline);
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001500
Deepa Dinamani33734bc2013-03-06 12:16:06 -08001501 dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d), tags/device tree @ %p\n",
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301502 entry, ramdisk, ramdisk_size, (void *)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001503
1504 enter_critical_section();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001505
Amol Jadi4421e652011-06-16 15:00:48 -07001506 /* do any platform specific cleanup before kernel entry */
1507 platform_uninit();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001508
Brian Swetland9c4c0752009-01-25 16:23:50 -08001509 arch_disable_cache(UCACHE);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001510
Amol Jadi504f9fe2012-08-16 13:56:48 -07001511#if ARM_WITH_MMU
Brian Swetland9c4c0752009-01-25 16:23:50 -08001512 arch_disable_mmu();
Amol Jadi504f9fe2012-08-16 13:56:48 -07001513#endif
Amol Jadi492d5a52013-03-15 16:12:34 -07001514 bs_set_timestamp(BS_KERNEL_ENTRY);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001515
1516 if (IS_ARM64(kptr))
1517 /* Jump to a 64bit kernel */
1518 scm_elexec_call((paddr_t)kernel, tags_phys);
1519 else
1520 /* Jump to a 32bit kernel */
1521 entry(0, machtype, (unsigned*)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001522}
1523
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001524/* Function to check if the memory address range falls within the aboot
1525 * boundaries.
1526 * start: Start of the memory region
1527 * size: Size of the memory region
1528 */
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301529int check_aboot_addr_range_overlap(uintptr_t start, uint32_t size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001530{
1531 /* Check for boundary conditions. */
Sundarajan Srinivasance2a0ea2013-12-16 17:02:56 -08001532 if ((UINT_MAX - start) < size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001533 return -1;
1534
1535 /* Check for memory overlap. */
1536 if ((start < MEMBASE) && ((start + size) <= MEMBASE))
1537 return 0;
Channagoud Kadabi94143912013-10-15 12:53:52 -07001538 else if (start >= (MEMBASE + MEMSIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001539 return 0;
1540 else
1541 return -1;
1542}
1543
Mayank Grovere559cec2017-10-17 15:12:03 +05301544/* Function to check if the memory address range falls beyond ddr region.
1545 * start: Start of the memory region
1546 * size: Size of the memory region
1547 */
1548int check_ddr_addr_range_bound(uintptr_t start, uint32_t size)
1549{
1550 uintptr_t ddr_pa_start_addr = PA(get_ddr_start());
1551 uint64_t ddr_size = smem_get_ddr_size();
1552 uint64_t ddr_pa_end_addr = ddr_pa_start_addr + ddr_size;
1553 uintptr_t pa_start_addr = PA(start);
1554
1555 /* Check for boundary conditions. */
1556 if ((UINT_MAX - start) < size)
1557 return -1;
1558
1559 /* Check if memory range is beyond the ddr range. */
1560 if (pa_start_addr < ddr_pa_start_addr ||
1561 pa_start_addr >= (ddr_pa_end_addr) ||
1562 (pa_start_addr + size) > ddr_pa_end_addr)
1563 return -1;
1564 else
1565 return 0;
1566}
1567
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001568BUF_DMA_ALIGN(buf, BOOT_IMG_MAX_PAGE_SIZE); //Equal to max-supported pagesize
Dima Zavin214cc642009-01-26 11:16:21 -08001569
Mayank Groverdd080e82018-09-04 20:12:13 +05301570int getimage(void **image_buffer, uint32_t *imgsize,
1571 const char *imgname)
Monika Singh292b3e92018-03-17 22:40:23 +05301572{
Mayank Groverdd080e82018-09-04 20:12:13 +05301573 uint32_t loadedindex;
1574 if (image_buffer == NULL || imgsize == NULL ||
Monika Singh292b3e92018-03-17 22:40:23 +05301575 imgname == NULL) {
1576 dprintf(CRITICAL, "getimage: invalid parameters\n");
1577 return -1;
1578 }
Mayank Groverdd080e82018-09-04 20:12:13 +05301579 for (loadedindex = 0; loadedindex < info.num_loaded_images; loadedindex++) {
1580 if (!strncmp(info.images[loadedindex].name, imgname,
Monika Singh292b3e92018-03-17 22:40:23 +05301581 strlen(imgname))) {
Mayank Groverdd080e82018-09-04 20:12:13 +05301582 *image_buffer = info.images[loadedindex].image_buffer;
1583 *imgsize = info.images[loadedindex].imgsize;
Mayank Grover027a9412018-09-04 15:12:05 +05301584 dprintf(SPEW, "getimage(): Loaded image [%s|%d]\n",
1585 info.images[loadedindex].name,
1586 info.images[loadedindex].imgsize);
Monika Singh292b3e92018-03-17 22:40:23 +05301587 return 0;
1588 }
1589 }
1590 return -1;
1591}
1592
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001593static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size)
1594{
1595 int ret;
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001596
1597#if !VERIFIED_BOOT
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001598#if IMAGE_VERIF_ALGO_SHA1
1599 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
1600#else
1601 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
1602#endif
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001603#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001604
1605 /* Assume device is rooted at this time. */
1606 device.is_tampered = 1;
1607
1608 dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
1609
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001610#if VERIFIED_BOOT
Monika Singh7d2fc272018-03-16 17:16:01 +05301611 uint32_t bootstate;
1612 if(boot_into_recovery &&
Mayank Grover68fbf0d2017-10-24 14:13:39 +05301613 (!partition_multislot_is_supported()))
Monika Singh7d2fc272018-03-16 17:16:01 +05301614 {
1615 ret = boot_verify_image((unsigned char *)bootimg_addr,
1616 bootimg_size, "/recovery", &bootstate);
1617 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001618 else
Monika Singh7d2fc272018-03-16 17:16:01 +05301619 {
1620 ret = boot_verify_image((unsigned char *)bootimg_addr,
1621 bootimg_size, "/boot", &bootstate);
1622 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001623 boot_verify_print_state();
1624#else
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001625 ret = image_verify((unsigned char *)bootimg_addr,
1626 (unsigned char *)(bootimg_addr + bootimg_size),
1627 bootimg_size,
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001628 auth_algo);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001629#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001630 dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret);
1631
1632 if (ret)
1633 {
1634 /* Authorized kernel */
1635 device.is_tampered = 0;
Sundarajan Srinivasan3fb21f12013-09-16 18:36:15 -07001636 auth_kernel_img = 1;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001637 }
1638
Amit Blay4aa292f2015-04-28 21:55:59 +03001639#ifdef MDTP_SUPPORT
1640 {
1641 /* Verify MDTP lock.
1642 * For boot & recovery partitions, use aboot's verification result.
1643 */
1644 mdtp_ext_partition_verification_t ext_partition;
1645 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
1646 ext_partition.integrity_state = device.is_tampered ? MDTP_PARTITION_STATE_INVALID : MDTP_PARTITION_STATE_VALID;
1647 ext_partition.page_size = 0; /* Not needed since already validated */
1648 ext_partition.image_addr = 0; /* Not needed since already validated */
1649 ext_partition.image_size = 0; /* Not needed since already validated */
1650 ext_partition.sig_avail = FALSE; /* Not needed since already validated */
1651 mdtp_fwlock_verify_lock(&ext_partition);
1652 }
1653#endif /* MDTP_SUPPORT */
1654
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001655#if USE_PCOM_SECBOOT
1656 set_tamper_flag(device.is_tampered);
1657#endif
1658
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001659#if VERIFIED_BOOT
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001660 switch(boot_verify_get_state())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001661 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001662 case RED:
lijuanga40d6302015-07-20 20:10:13 +08001663#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001664 display_bootverify_menu(DISPLAY_MENU_RED);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001665#if ENABLE_VB_ATTEST
1666 mdelay(DELAY_WAIT);
1667 shutdown_device();
1668#else
lijuanga40d6302015-07-20 20:10:13 +08001669 wait_for_users_action();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001670#endif
lijuanga40d6302015-07-20 20:10:13 +08001671#else
1672 dprintf(CRITICAL,
1673 "Your device has failed verification and may not work properly.\nWait for 5 seconds before proceeding\n");
1674 mdelay(5000);
1675#endif
1676
1677 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001678 case YELLOW:
lijuanga40d6302015-07-20 20:10:13 +08001679#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001680 display_bootverify_menu(DISPLAY_MENU_YELLOW);
lijuanga40d6302015-07-20 20:10:13 +08001681 wait_for_users_action();
1682#else
1683 dprintf(CRITICAL,
1684 "Your device has loaded a different operating system.\nWait for 5 seconds before proceeding\n");
1685 mdelay(5000);
1686#endif
1687 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001688 default:
lijuanga40d6302015-07-20 20:10:13 +08001689 break;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001690 }
1691#endif
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001692#if !VERIFIED_BOOT
Unnati Gandhi1be04752015-03-27 19:41:53 +05301693 if(device.is_tampered)
1694 {
1695 write_device_info_mmc(&device);
1696 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05301697 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Unnati Gandhi1be04752015-03-27 19:41:53 +05301698 #endif
1699 #ifdef ASSERT_ON_TAMPER
1700 dprintf(CRITICAL, "Device is tampered. Asserting..\n");
1701 ASSERT(0);
1702 #endif
1703 }
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001704#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001705}
1706
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301707static bool check_format_bit()
1708{
1709 bool ret = false;
1710 int index;
1711 uint64_t offset;
1712 struct boot_selection_info *in = NULL;
1713 char *buf = NULL;
1714
1715 index = partition_get_index("bootselect");
1716 if (index == INVALID_PTN)
1717 {
1718 dprintf(INFO, "Unable to locate /bootselect partition\n");
1719 return ret;
1720 }
1721 offset = partition_get_offset(index);
1722 if(!offset)
1723 {
1724 dprintf(INFO, "partition /bootselect doesn't exist\n");
1725 return ret;
1726 }
1727 buf = (char *) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE));
Mayank Grover48860402016-11-29 12:34:53 +05301728 mmc_set_lun(partition_get_lun(index));
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301729 ASSERT(buf);
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301730 if (mmc_read(offset, (uint32_t *)buf, page_size))
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301731 {
1732 dprintf(INFO, "mmc read failure /bootselect %d\n", page_size);
1733 free(buf);
1734 return ret;
1735 }
1736 in = (struct boot_selection_info *) buf;
1737 if ((in->signature == BOOTSELECT_SIGNATURE) &&
1738 (in->version == BOOTSELECT_VERSION)) {
1739 if ((in->state_info & BOOTSELECT_FORMAT) &&
1740 !(in->state_info & BOOTSELECT_FACTORY))
1741 ret = true;
1742 } else {
1743 dprintf(CRITICAL, "Signature: 0x%08x or version: 0x%08x mismatched of /bootselect\n",
1744 in->signature, in->version);
1745 ASSERT(0);
1746 }
1747 free(buf);
1748 return ret;
1749}
1750
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001751void boot_verifier_init()
1752{
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001753 uint32_t boot_state;
1754 /* Check if device unlock */
1755 if(device.is_unlocked)
1756 {
1757 boot_verify_send_event(DEV_UNLOCK);
1758 boot_verify_print_state();
1759 dprintf(CRITICAL, "Device is unlocked! Skipping verification...\n");
1760 return;
1761 }
1762 else
1763 {
1764 boot_verify_send_event(BOOT_INIT);
1765 }
1766
1767 /* Initialize keystore */
1768 boot_state = boot_verify_keystore_init();
1769 if(boot_state == YELLOW)
1770 {
1771 boot_verify_print_state();
1772 dprintf(CRITICAL, "Keystore verification failed! Continuing anyways...\n");
1773 }
1774}
1775
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301776/* Function to return recovery appended dtbo buffer info */
1777void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf)
1778{
1779 *dtbo_size = recovery_dtbo_size;
1780 *dtbo_buf = recovery_dtbo_buf;
1781 return;
1782}
1783
Shashank Mittal23b8f422010-04-16 19:27:21 -07001784int boot_linux_from_mmc(void)
1785{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301786 boot_img_hdr *hdr = (void*) buf;
1787 boot_img_hdr *uhdr;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001788 unsigned offset = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001789 int rcode;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001790 unsigned long long ptn = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07001791 int index = INVALID_PTN;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001792
Shashank Mittalcd98d472011-08-02 14:29:24 -07001793 unsigned char *image_addr = 0;
1794 unsigned kernel_actual;
1795 unsigned ramdisk_actual;
1796 unsigned imagesize_actual;
Neeti Desai465491e2012-07-31 12:53:35 -07001797 unsigned second_actual = 0;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301798 void * image_buf = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001799
Matthew Qin271927e2015-03-31 22:07:07 -04001800 unsigned int dtb_size = 0;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301801 unsigned dtb_image_size = 0;
1802 uint32_t dtb_image_offset = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001803 unsigned int out_len = 0;
1804 unsigned int out_avai_len = 0;
1805 unsigned char *out_addr = NULL;
1806 uint32_t dtb_offset = 0;
1807 unsigned char *kernel_start_addr = NULL;
1808 unsigned int kernel_size = 0;
Ameya Thakur10a33452016-06-13 14:24:26 -07001809 unsigned int patched_kernel_hdr_size = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301810 uint64_t image_size = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001811 int rc;
Monika Singh292b3e92018-03-17 22:40:23 +05301812#if VERIFIED_BOOT_2
1813 int status;
Mayank Grover027a9412018-09-04 15:12:05 +05301814 void *dtbo_image_buf = NULL;
1815 uint32_t dtbo_image_sz = 0;
Mayank Grover9df84c02018-08-30 15:46:35 +05301816 void *vbmeta_image_buf = NULL;
1817 uint32_t vbmeta_image_sz = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05301818#endif
Mayank Groverc93cad82017-10-03 12:23:45 +05301819 char *ptn_name = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001820#if DEVICE_TREE
1821 struct dt_table *table;
Joel Kingaa335dc2013-06-03 16:11:08 -07001822 struct dt_entry dt_entry;
Neeti Desai465491e2012-07-31 12:53:35 -07001823 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001824 uint32_t dt_actual;
Deepa Dinamani19648b42013-09-05 17:05:55 -07001825 uint32_t dt_hdr_size;
Matthew Qin271927e2015-03-31 22:07:07 -04001826 unsigned char *best_match_dt_addr = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001827#endif
Matthew Qin49e51fa2015-02-09 10:40:45 +08001828 struct kernel64_hdr *kptr = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05301829 int current_active_slot = INVALID;
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001830
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301831 if (check_format_bit())
1832 boot_into_recovery = 1;
1833
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001834 if (!boot_into_recovery) {
1835 memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string));
1836 rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string));
1837 if (rcode <= 0) {
1838 boot_into_ffbm = false;
1839 if (rcode < 0)
1840 dprintf(CRITICAL,"failed to get ffbm cookie");
1841 } else
1842 boot_into_ffbm = true;
1843 } else
1844 boot_into_ffbm = false;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301845 uhdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001846 if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
1847 dprintf(INFO, "Unified boot method!\n");
1848 hdr = uhdr;
1849 goto unified_boot;
1850 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301851
1852 /* For a/b recovery image code is on boot partition.
1853 If we support multislot, always use boot partition. */
1854 if (boot_into_recovery &&
Mayank Grover8ab4a762019-04-25 17:23:34 +05301855 ((!partition_multislot_is_supported()) ||
1856 (target_dynamic_partition_supported())))
Mayank Groverc93cad82017-10-03 12:23:45 +05301857 ptn_name = "recovery";
1858 else
1859 ptn_name = "boot";
1860
1861 index = partition_get_index(ptn_name);
1862 ptn = partition_get_offset(index);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301863 image_size = partition_get_size(index);
1864 if(ptn == 0 || image_size == 0) {
Mayank Groverc93cad82017-10-03 12:23:45 +05301865 dprintf(CRITICAL, "ERROR: No %s partition found\n", ptn_name);
1866 return -1;
Kinson Chikf1a43512011-07-14 11:28:39 -07001867 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301868
Channagoud Kadabief0547c2015-02-10 12:57:38 -08001869 /* Set Lun for boot & recovery partitions */
1870 mmc_set_lun(partition_get_lun(index));
Shashank Mittal23b8f422010-04-16 19:27:21 -07001871
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301872 if (mmc_read(ptn + offset, (uint32_t *) buf, page_size)) {
Shashank Mittal23b8f422010-04-16 19:27:21 -07001873 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
1874 return -1;
1875 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07001876
1877 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07001878 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Mayank Grover351a75e2017-05-30 20:06:08 +05301879 return ERR_INVALID_BOOT_MAGIC;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001880 }
1881
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001882 if (hdr->page_size && (hdr->page_size != page_size)) {
vijay kumar2e21b3a2014-06-26 17:40:15 +05301883
1884 if (hdr->page_size > BOOT_IMG_MAX_PAGE_SIZE) {
1885 dprintf(CRITICAL, "ERROR: Invalid page size\n");
1886 return -1;
1887 }
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001888 page_size = hdr->page_size;
1889 page_mask = page_size - 1;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001890 }
1891
Matthew Qin49e51fa2015-02-09 10:40:45 +08001892 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1893 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301894 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001895
Matthew Qin49e51fa2015-02-09 10:40:45 +08001896 image_addr = (unsigned char *)target_get_scratch_address();
Mayank Grover6fd36792018-09-10 13:26:58 +05301897#if VERIFIED_BOOT_2
1898 /* Create hole in start of image for VB salt to copy */
1899 image_addr += SALT_BUFF_OFFSET;
1900#endif
Kishor PK9e91b592017-05-24 12:14:55 +05301901 memcpy(image_addr, (void *)buf, page_size);
1902
1903 /* ensure commandline is terminated */
1904 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001905
1906#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05301907#ifndef OSVERSION_IN_BOOTIMAGE
1908 dt_size = hdr->dt_size;
Mayank Grover5a502582018-09-12 11:24:49 +05301909#else
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301910 dprintf(INFO, "BootImage Header: %d\n", hdr->header_version);
Mayank Grover5a502582018-09-12 11:24:49 +05301911#endif
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301912
Parth Dixit4097b622016-03-15 14:42:27 +05301913 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301914 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 +05301915 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1916 return -1;
1917 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301918 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001919#else
Kishor PKd8ddcad2017-07-27 13:53:57 +05301920 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 +05301921 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1922 return -1;
1923 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301924 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001925#endif
Parth Dixit1375d9e2019-07-08 20:56:13 +05301926 dtb_image_size = hdr->kernel_size;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001927
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301928#ifdef OSVERSION_IN_BOOTIMAGE
1929 /* If header version is ONE and booting into recovery,
1930 dtbo is appended with recovery image.
1931 Doing following:
1932 * Validating the recovery offset and size.
1933 * Extracting recovery dtbo to be used as dtbo.
1934 */
1935 if (boot_into_recovery &&
1936 hdr->header_version == BOOT_HEADER_VERSION_ONE)
1937 {
1938 struct boot_img_hdr_v1 *hdr1 =
1939 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
Mayank Grovera1a83c72018-09-24 11:23:15 +05301940 unsigned int recovery_dtbo_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301941
Mayank Grovera1a83c72018-09-24 11:23:15 +05301942 recovery_dtbo_actual = ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301943 if ((hdr1->header_size !=
1944 sizeof(struct boot_img_hdr_v1) + sizeof(boot_img_hdr)))
1945 {
1946 dprintf(CRITICAL, "Invalid boot image header: %d\n", hdr1->header_size);
1947 return -1;
1948 }
1949
Mayank Grovera1a83c72018-09-24 11:23:15 +05301950 if (recovery_dtbo_actual > MAX_SUPPORTED_DTBO_IMG_BUF)
1951 {
1952 dprintf(CRITICAL, "Recovery Dtbo Size too big %x, Allowed size %x\n", recovery_dtbo_actual,
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301953 MAX_SUPPORTED_DTBO_IMG_BUF);
1954 return -1;
1955 }
1956
Mayank Grovera1a83c72018-09-24 11:23:15 +05301957 if (UINT_MAX < ((uint64_t)imagesize_actual + recovery_dtbo_actual))
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301958 {
1959 dprintf(CRITICAL, "Integer overflow detected in recoveryimage header fields at %u in %s\n",__LINE__,__FILE__);
1960 return -1;
1961 }
1962
Mayank Grovera1a83c72018-09-24 11:23:15 +05301963 if (UINT_MAX < (hdr1->recovery_dtbo_offset + recovery_dtbo_actual)) {
1964 dprintf(CRITICAL,
1965 "Integer overflow detected in recovery image header fields at %u in %s\n",__LINE__,__FILE__);
1966 return -1;
1967 }
1968
1969 if (hdr1->recovery_dtbo_offset + recovery_dtbo_actual > image_size)
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301970 {
1971 dprintf(CRITICAL, "Invalid recovery dtbo: Recovery Dtbo Offset=0x%llx,"
1972 " Recovery Dtbo Size=0x%x, Image Size=0x%llx\n",
1973 hdr1->recovery_dtbo_offset, recovery_dtbo_size, image_size);
1974 return -1;
1975 }
1976
1977 recovery_dtbo_buf = (void *)(hdr1->recovery_dtbo_offset + image_addr);
Mayank Grovera1a83c72018-09-24 11:23:15 +05301978 recovery_dtbo_size = recovery_dtbo_actual;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301979 imagesize_actual += recovery_dtbo_size;
1980
1981 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
1982 dprintf(SPEW, "Recovery Dtbo Size 0x%x\n", recovery_dtbo_size);
1983 dprintf(SPEW, "Recovery Dtbo Offset 0x%llx\n", hdr1->recovery_dtbo_offset);
1984
1985 }
Parth Dixit1375d9e2019-07-08 20:56:13 +05301986
1987 if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
1988 struct boot_img_hdr_v1 *hdr1 =
1989 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
1990 struct boot_img_hdr_v2 *hdr2 = (struct boot_img_hdr_v2 *)
1991 (image_addr + sizeof(boot_img_hdr) +
1992 BOOT_IMAGE_HEADER_V2_OFFSET);
1993 unsigned int recovery_dtbo_actual = 0;
1994
lijuang0b17ba22019-09-04 14:20:47 +08001995 recovery_dtbo_actual =
1996 ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
1997 imagesize_actual += recovery_dtbo_actual;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301998
1999 imagesize_actual += ROUND_TO_PAGE(hdr2->dtb_size, page_mask);
2000
2001
2002 dtb_image_offset = page_size + patched_kernel_hdr_size +
2003 kernel_actual + ramdisk_actual + second_actual +
2004 recovery_dtbo_actual;
2005
2006 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
2007 dprintf(SPEW, "Dtb image offset 0x%x\n", dtb_image_offset);
2008 }
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302009#endif
2010
Parth Dixit1375d9e2019-07-08 20:56:13 +05302011
Saranya Chidurab1aaf232018-11-19 15:47:50 +05302012 /* Validate the boot/recovery image size is within the bounds of partition size */
2013 if (imagesize_actual > image_size) {
2014 dprintf(CRITICAL, "Image size is greater than partition size.\n");
2015 return -1;
2016 }
2017
Matthew Qin49e51fa2015-02-09 10:40:45 +08002018#if VERIFIED_BOOT
2019 boot_verifier_init();
2020#endif
2021
Mayank Grover1ceaee22019-04-01 17:54:32 +05302022#if VERIFIED_BOOT_2
2023 /* read full partition if device is unlocked */
2024 if (device.is_unlocked)
2025 imagesize_actual = image_size;
2026#endif
2027
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05302028 if (check_aboot_addr_range_overlap((uintptr_t) image_addr, imagesize_actual))
Matthew Qin49e51fa2015-02-09 10:40:45 +08002029 {
2030 dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
2031 return -1;
2032 }
2033
Matthew Qinbb7923d2015-02-09 10:56:09 +08002034 /*
2035 * Update loading flow of bootimage to support compressed/uncompressed
2036 * bootimage on both 64bit and 32bit platform.
2037 * 1. Load bootimage from emmc partition onto DDR.
2038 * 2. Check if bootimage is gzip format. If yes, decompress compressed kernel
2039 * 3. Check kernel header and update kernel load addr for 64bit and 32bit
2040 * platform accordingly.
2041 * 4. Sanity Check on kernel_addr and ramdisk_addr and copy data.
2042 */
Mayank Grover351a75e2017-05-30 20:06:08 +05302043 if (partition_multislot_is_supported())
2044 {
2045 current_active_slot = partition_find_active_slot();
2046 dprintf(INFO, "Loading boot image (%d) active_slot(%s): start\n",
2047 imagesize_actual, SUFFIX_SLOT(current_active_slot));
2048 }
2049 else
2050 {
2051 dprintf(INFO, "Loading (%s) image (%d): start\n",
2052 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2053 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002054 bs_set_timestamp(BS_KERNEL_LOAD_START);
2055
Gaurav Nebhwani43e2a462016-03-17 21:32:56 +05302056 if ((target_get_max_flash_size() - page_size) < imagesize_actual)
2057 {
2058 dprintf(CRITICAL, "booimage size is greater than DDR can hold\n");
2059 return -1;
2060 }
Kishor PK9e91b592017-05-24 12:14:55 +05302061 offset = page_size;
2062 /* Read image without signature and header*/
2063 if (mmc_read(ptn + offset, (void *)(image_addr + offset), imagesize_actual - page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08002064 {
2065 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
2066 return -1;
2067 }
2068
Mayank Grover351a75e2017-05-30 20:06:08 +05302069 if (partition_multislot_is_supported())
2070 {
2071 dprintf(INFO, "Loading boot image (%d) active_slot(%s): done\n",
2072 imagesize_actual, SUFFIX_SLOT(current_active_slot));
2073 }
2074 else
2075 {
2076 dprintf(INFO, "Loading (%s) image (%d): done\n",
Channagoud Kadabif0705b52015-08-20 14:16:08 -07002077 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2078
Mayank Grover351a75e2017-05-30 20:06:08 +05302079 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002080 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
2081
2082 /* Authenticate Kernel */
2083 dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
2084 (int) target_use_signed_kernel(),
2085 device.is_unlocked,
2086 device.is_tampered);
Monika Singh292b3e92018-03-17 22:40:23 +05302087#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05302088 /* if device is unlocked skip reading signature, as full partition is read */
2089 if (!device.is_unlocked)
Monika Singh292b3e92018-03-17 22:40:23 +05302090 {
Mayank Grover1ceaee22019-04-01 17:54:32 +05302091 offset = imagesize_actual;
2092 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
2093 {
2094 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
2095 return -1;
2096 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002097
Mayank Grover1ceaee22019-04-01 17:54:32 +05302098 /* Read signature */
2099 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
2100 {
2101 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
2102 return -1;
2103 }
Monika Singh292b3e92018-03-17 22:40:23 +05302104 }
2105
Mayank Grover027a9412018-09-04 15:12:05 +05302106 /* load and validate dtbo partition */
2107 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
2108
Mayank Grover9df84c02018-08-30 15:46:35 +05302109 /* load vbmeta partition */
2110 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
2111
Monika Singh292b3e92018-03-17 22:40:23 +05302112 memset(&info, 0, sizeof(bootinfo));
Mayank Grover027a9412018-09-04 15:12:05 +05302113
2114 /* Pass loaded boot image passed */
Mayank Grover6fd36792018-09-10 13:26:58 +05302115 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(image_addr);
Mayank Grover027a9412018-09-04 15:12:05 +05302116 info.images[IMG_BOOT].imgsize = imagesize_actual;
2117 info.images[IMG_BOOT].name = ptn_name;
2118 ++info.num_loaded_images;
2119
2120 /* Pass loaded dtbo image */
2121 if (dtbo_image_buf != NULL) {
Mayank Grover6fd36792018-09-10 13:26:58 +05302122 info.images[IMG_DTBO].image_buffer =
2123 SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
Mayank Grover027a9412018-09-04 15:12:05 +05302124 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
2125 info.images[IMG_DTBO].name = "dtbo";
2126 ++info.num_loaded_images;
2127 }
2128
Mayank Grover9df84c02018-08-30 15:46:35 +05302129 /* Pass loaded vbmeta image */
2130 if (vbmeta_image_buf != NULL) {
2131 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
2132 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
2133 info.images[IMG_VBMETA].name = "vbmeta";
2134 ++info.num_loaded_images;
2135 }
2136
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302137 info.header_version = hdr->header_version;
Monika Singh292b3e92018-03-17 22:40:23 +05302138 info.multi_slot_boot = partition_multislot_is_supported();
2139 info.bootreason_alarm = boot_reason_alarm;
2140 info.bootinto_recovery = boot_into_recovery;
2141 status = load_image_and_auth(&info);
2142 if(status)
2143 return -1;
2144
2145 vbcmdline = info.vbcmdline;
Mayank Grover9df84c02018-08-30 15:46:35 +05302146
2147 /* Free the buffer allocated to vbmeta post verification */
Saranya Chidurab4933332018-10-15 17:30:06 +05302148 if (vbmeta_image_buf != NULL) {
2149 free(vbmeta_image_buf);
2150 --info.num_loaded_images;
2151 }
Monika Singh292b3e92018-03-17 22:40:23 +05302152#else
Channagoud Kadabi736c4962015-08-21 11:56:52 -07002153 /* Change the condition a little bit to include the test framework support.
2154 * We would never reach this point if device is in fastboot mode, even if we did
2155 * that means we are in test mode, so execute kernel authentication part for the
2156 * tests */
Parth Dixitcb0c6082015-12-30 15:01:13 +05302157 if((target_use_signed_kernel() && (!device.is_unlocked)) || is_test_mode_enabled())
Matthew Qin49e51fa2015-02-09 10:40:45 +08002158 {
2159 offset = imagesize_actual;
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05302160 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08002161 {
2162 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
2163 return -1;
2164 }
2165
2166 /* Read signature */
2167 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
2168 {
2169 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
2170 return -1;
2171 }
2172
2173 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Channagoud Kadabi736c4962015-08-21 11:56:52 -07002174 /* The purpose of our test is done here */
Parth Dixitcb0c6082015-12-30 15:01:13 +05302175 if(is_test_mode_enabled() && auth_kernel_img)
Channagoud Kadabi736c4962015-08-21 11:56:52 -07002176 return 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08002177 } else {
2178 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
2179 #ifdef TZ_SAVE_KERNEL_HASH
2180 aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
2181 #endif /* TZ_SAVE_KERNEL_HASH */
Amit Blay4aa292f2015-04-28 21:55:59 +03002182
2183#ifdef MDTP_SUPPORT
2184 {
2185 /* Verify MDTP lock.
2186 * For boot & recovery partitions, MDTP will use boot_verifier APIs,
2187 * since verification was skipped in aboot. The signature is not part of the loaded image.
2188 */
2189 mdtp_ext_partition_verification_t ext_partition;
2190 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
2191 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
2192 ext_partition.page_size = page_size;
2193 ext_partition.image_addr = (uint32)image_addr;
2194 ext_partition.image_size = imagesize_actual;
2195 ext_partition.sig_avail = FALSE;
2196 mdtp_fwlock_verify_lock(&ext_partition);
2197 }
2198#endif /* MDTP_SUPPORT */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002199 }
Monika Singh292b3e92018-03-17 22:40:23 +05302200#endif
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002201
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -07002202#if VERIFIED_BOOT
taozhang93088bd2016-11-16 15:50:46 +08002203 if((boot_verify_get_state() == ORANGE) && (!boot_into_ffbm))
Reut Zysmanba8a9d52016-02-18 11:44:04 +02002204 {
2205#if FBCON_DISPLAY_MSG
2206 display_bootverify_menu(DISPLAY_MENU_ORANGE);
2207 wait_for_users_action();
2208#else
2209 dprintf(CRITICAL,
2210 "Your device has been unlocked and can't be trusted.\nWait for 5 seconds before proceeding\n");
2211 mdelay(5000);
2212#endif
2213 }
2214#endif
2215
2216#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05302217 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302218 {
2219 /* set boot and system versions. */
2220 set_os_version((unsigned char *)image_addr);
2221 // send root of trust
2222 if(!send_rot_command((uint32_t)device.is_unlocked))
2223 ASSERT(0);
2224 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05302225#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002226 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08002227 * Check if the kernel image is a gzip package. If yes, need to decompress it.
2228 * If not, continue booting.
2229 */
2230 if (is_gzip_package((unsigned char *)(image_addr + page_size), hdr->kernel_size))
2231 {
2232 out_addr = (unsigned char *)(image_addr + imagesize_actual + page_size);
2233 out_avai_len = target_get_max_flash_size() - imagesize_actual - page_size;
Mayank Grover027a9412018-09-04 15:12:05 +05302234#if VERIFIED_BOOT_2
2235 if (dtbo_image_sz)
2236 out_avai_len -= DTBO_IMG_BUF;
2237#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04002238 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08002239 rc = decompress((unsigned char *)(image_addr + page_size),
2240 hdr->kernel_size, out_addr, out_avai_len,
2241 &dtb_offset, &out_len);
2242 if (rc)
2243 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002244 dprintf(CRITICAL, "decompressing kernel image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08002245 ASSERT(0);
2246 }
2247
Matthew Qin0b15b322015-05-19 05:20:54 -04002248 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08002249 kptr = (struct kernel64_hdr *)out_addr;
2250 kernel_start_addr = out_addr;
2251 kernel_size = out_len;
2252 } else {
Ameya Thakur10a33452016-06-13 14:24:26 -07002253 dprintf(INFO, "Uncpmpressed kernel in use\n");
2254 if (!strncmp((char*)(image_addr + page_size),
2255 PATCHED_KERNEL_MAGIC,
2256 sizeof(PATCHED_KERNEL_MAGIC) - 1)) {
2257 dprintf(INFO, "Patched kernel detected\n");
2258 kptr = (struct kernel64_hdr *)(image_addr + page_size +
2259 PATCHED_KERNEL_HEADER_SIZE);
2260 //The size of the kernel is stored at start of kernel image + 16
2261 //The dtb would start just after the kernel
2262 dtb_offset = *((uint32_t*)((unsigned char*)
2263 (image_addr + page_size +
2264 sizeof(PATCHED_KERNEL_MAGIC) -
2265 1)));
2266 //The actual kernel starts after the 20 byte header.
2267 kernel_start_addr = (unsigned char*)(image_addr +
2268 page_size + PATCHED_KERNEL_HEADER_SIZE);
2269 kernel_size = hdr->kernel_size;
2270 patched_kernel_hdr_size = PATCHED_KERNEL_HEADER_SIZE;
2271 } else {
2272 dprintf(INFO, "Kernel image not patched..Unable to locate dt offset\n");
2273 kptr = (struct kernel64_hdr *)(image_addr + page_size);
2274 kernel_start_addr = (unsigned char *)(image_addr + page_size);
2275 kernel_size = hdr->kernel_size;
2276 }
Matthew Qinbb7923d2015-02-09 10:56:09 +08002277 }
2278
2279 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002280 * Update the kernel/ramdisk/tags address if the boot image header
2281 * has default values, these default values come from mkbootimg when
2282 * the boot image is flashed using fastboot flash:raw
2283 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002284 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002285
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002286 /* Get virtual addresses since the hdr saves physical addresses. */
2287 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
2288 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
2289 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002290
Matthew Qinbb7923d2015-02-09 10:56:09 +08002291 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002292 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08002293 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05302294 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
2295 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
2296 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002297 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302298 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002299 return -1;
2300 }
2301
2302#ifndef DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05302303 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2304 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002305 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302306 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002307 return -1;
2308 }
2309#endif
2310
Matthew Qin49e51fa2015-02-09 10:40:45 +08002311 /* Move kernel, ramdisk and device tree to correct address */
Matthew Qinbb7923d2015-02-09 10:56:09 +08002312 memmove((void*) hdr->kernel_addr, kernel_start_addr, kernel_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002313 memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07002314
Matthew Qin49e51fa2015-02-09 10:40:45 +08002315 #if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05302316 if(dt_size) {
Matthew Qin49e51fa2015-02-09 10:40:45 +08002317 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2318 table = (struct dt_table*) dt_table_offset;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002319
Matthew Qin49e51fa2015-02-09 10:40:45 +08002320 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2321 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2322 return -1;
2323 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002324
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302325 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2326 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05302327 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302328 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2329 return -1;
2330 }
2331
Matthew Qin49e51fa2015-02-09 10:40:45 +08002332 /* Find index of device tree within device tree table */
2333 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2334 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2335 return -1;
2336 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002337
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05302338 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2339 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2340 return -1;
2341 }
2342
2343 /* Ensure we are not overshooting dt_size with the dt_entry selected */
Parth Dixit4097b622016-03-15 14:42:27 +05302344 if ((dt_entry.offset + dt_entry.size) > dt_size) {
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05302345 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2346 return -1;
2347 }
2348
Matthew Qin271927e2015-03-31 22:07:07 -04002349 if (is_gzip_package((unsigned char *)dt_table_offset + dt_entry.offset, dt_entry.size))
2350 {
2351 unsigned int compressed_size = 0;
2352 out_addr += out_len;
2353 out_avai_len -= out_len;
Matthew Qin0b15b322015-05-19 05:20:54 -04002354 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002355 rc = decompress((unsigned char *)dt_table_offset + dt_entry.offset,
2356 dt_entry.size, out_addr, out_avai_len,
2357 &compressed_size, &dtb_size);
2358 if (rc)
2359 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002360 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002361 ASSERT(0);
2362 }
2363
Matthew Qin0b15b322015-05-19 05:20:54 -04002364 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002365 best_match_dt_addr = out_addr;
2366 } else {
2367 best_match_dt_addr = (unsigned char *)dt_table_offset + dt_entry.offset;
2368 dtb_size = dt_entry.size;
2369 }
2370
Matthew Qin49e51fa2015-02-09 10:40:45 +08002371 /* Validate and Read device device tree in the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302372 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
2373 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002374 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302375 dprintf(CRITICAL, "Device tree addresses are not valid\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002376 return -1;
2377 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002378
Matthew Qin271927e2015-03-31 22:07:07 -04002379 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002380 } else {
2381 /* Validate the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302382 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2383 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002384 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302385 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002386 return -1;
2387 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002388 /*
2389 * If appended dev tree is found, update the atags with
2390 * memory address to the DTB appended location on RAM.
2391 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302392 *
2393 * Make sure everything from scratch address is read before next step!
2394 * In case of dtbo, this API is going to read dtbo on scratch.
Matthew Qin49e51fa2015-02-09 10:40:45 +08002395 */
2396 void *dtb;
Parth Dixit1375d9e2019-07-08 20:56:13 +05302397 image_buf = (void*)(image_addr + page_size + patched_kernel_hdr_size);
2398
Nagireddy Annem0d60bb62019-08-16 19:16:00 +05302399#ifdef OSVERSION_IN_BOOTIMAGE
Parth Dixit1375d9e2019-07-08 20:56:13 +05302400 if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
2401
2402 image_buf = (void*)(image_addr);
2403 dtb_offset = dtb_image_offset;
2404 dtb_image_size = imagesize_actual;
2405 }
Nagireddy Annem0d60bb62019-08-16 19:16:00 +05302406#endif
Parth Dixit1375d9e2019-07-08 20:56:13 +05302407
2408 dtb = dev_tree_appended(image_buf, dtb_image_size, dtb_offset,
Ameya Thakur10a33452016-06-13 14:24:26 -07002409 (void *)hdr->tags_addr);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002410 if (!dtb) {
2411 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002412 return -1;
2413 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002414 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002415 #endif
Shashank Mittal23b8f422010-04-16 19:27:21 -07002416
Stanimir Varbanov69ec5462013-07-18 18:17:42 +03002417 if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
2418 target_load_ssd_keystore();
2419
Shashank Mittal23b8f422010-04-16 19:27:21 -07002420unified_boot:
Shashank Mittal23b8f422010-04-16 19:27:21 -07002421
Dima Zavin77e41f32013-03-06 16:10:43 -08002422 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002423 (const char *)hdr->cmdline, board_machtype(),
Shashank Mittal23b8f422010-04-16 19:27:21 -07002424 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2425
2426 return 0;
2427}
2428
Dima Zavin214cc642009-01-26 11:16:21 -08002429int boot_linux_from_flash(void)
2430{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302431 boot_img_hdr *hdr = (void*) buf;
Dima Zavin214cc642009-01-26 11:16:21 -08002432 struct ptentry *ptn;
2433 struct ptable *ptable;
2434 unsigned offset = 0;
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002435
Shashank Mittalcd98d472011-08-02 14:29:24 -07002436 unsigned char *image_addr = 0;
2437 unsigned kernel_actual;
2438 unsigned ramdisk_actual;
2439 unsigned imagesize_actual;
vijay kumar8f53e362015-11-24 13:38:11 +05302440 unsigned second_actual = 0;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002441
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002442#if DEVICE_TREE
Monika Singh292b3e92018-03-17 22:40:23 +05302443 struct dt_table *table = NULL;
Joel Kingaa335dc2013-06-03 16:11:08 -07002444 struct dt_entry dt_entry;
vijay kumar8f53e362015-11-24 13:38:11 +05302445 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08002446 uint32_t dt_actual;
Monika Singh292b3e92018-03-17 22:40:23 +05302447 uint32_t dt_hdr_size = 0;
Vivek Kumar07bd0862018-04-10 14:19:23 +05302448 uint32_t dtb_offset = 0;
vijay kumar8f53e362015-11-24 13:38:11 +05302449 unsigned int dtb_size = 0;
2450 unsigned char *best_match_dt_addr = NULL;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002451#endif
2452
David Ng183a7422009-12-07 14:55:21 -08002453 if (target_is_emmc_boot()) {
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302454 hdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
David Ng183a7422009-12-07 14:55:21 -08002455 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
2456 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
2457 return -1;
2458 }
2459 goto continue_boot;
2460 }
2461
Dima Zavin214cc642009-01-26 11:16:21 -08002462 ptable = flash_get_ptable();
2463 if (ptable == NULL) {
2464 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2465 return -1;
2466 }
2467
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002468 if(!boot_into_recovery)
2469 {
2470 ptn = ptable_find(ptable, "boot");
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002471
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002472 if (ptn == NULL) {
2473 dprintf(CRITICAL, "ERROR: No boot partition found\n");
2474 return -1;
2475 }
2476 }
2477 else
2478 {
2479 ptn = ptable_find(ptable, "recovery");
2480 if (ptn == NULL) {
2481 dprintf(CRITICAL, "ERROR: No recovery partition found\n");
2482 return -1;
2483 }
Dima Zavin214cc642009-01-26 11:16:21 -08002484 }
2485
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302486 /* Read boot.img header from flash */
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002487 if (flash_read(ptn, offset, buf, page_size)) {
Dima Zavin214cc642009-01-26 11:16:21 -08002488 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
2489 return -1;
2490 }
Dima Zavin214cc642009-01-26 11:16:21 -08002491
2492 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002493 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Dima Zavin214cc642009-01-26 11:16:21 -08002494 return -1;
2495 }
2496
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002497 if (hdr->page_size != page_size) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002498 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 -08002499 return -1;
2500 }
2501
Kishor PK9e91b592017-05-24 12:14:55 +05302502 image_addr = (unsigned char *)target_get_scratch_address();
2503 memcpy(image_addr, (void *)buf, page_size);
vijay kumar287bb542015-09-29 13:01:52 +05302504
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002505 /*
2506 * Update the kernel/ramdisk/tags address if the boot image header
2507 * has default values, these default values come from mkbootimg when
2508 * the boot image is flashed using fastboot flash:raw
2509 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002510 update_ker_tags_rdisk_addr(hdr, false);
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002511
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002512 /* Get virtual addresses since the hdr saves physical addresses. */
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002513 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
2514 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
2515 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
2516
2517 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
2518 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Mayank Grover032736f2017-07-14 20:34:51 +05302519 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002520
Kishor PK9e91b592017-05-24 12:14:55 +05302521 /* ensure commandline is terminated */
2522 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
2523
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002524 /* Check if the addresses in the header are valid. */
2525 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05302526 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_actual) ||
2527 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
2528 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002529 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302530 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002531 return -1;
2532 }
2533
2534#ifndef DEVICE_TREE
Kishor PKd8ddcad2017-07-27 13:53:57 +05302535 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + page_size)) {
Mayank Grover032736f2017-07-14 20:34:51 +05302536 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2537 return -1;
2538 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05302539 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302540
Mayank Grovere559cec2017-10-17 15:12:03 +05302541 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2542 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302543 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302544 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302545 return -1;
2546 }
2547#else
2548
2549#ifndef OSVERSION_IN_BOOTIMAGE
2550 dt_size = hdr->dt_size;
2551#endif
Mayank Grover032736f2017-07-14 20:34:51 +05302552 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05302553 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 +05302554 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2555 return -1;
2556 }
2557
Kishor PKd8ddcad2017-07-27 13:53:57 +05302558 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302559
Mayank Grovere559cec2017-10-17 15:12:03 +05302560 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size) ||
2561 check_ddr_addr_range_bound(hdr->tags_addr, dt_size))
Mayank Grover032736f2017-07-14 20:34:51 +05302562 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302563 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Mayank Grover032736f2017-07-14 20:34:51 +05302564 return -1;
2565 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002566#endif
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002567
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302568 /* Read full boot.img from flash */
2569 dprintf(INFO, "Loading (%s) image (%d): start\n",
2570 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2571 bs_set_timestamp(BS_KERNEL_LOAD_START);
2572
2573 if (UINT_MAX - page_size < imagesize_actual)
2574 {
2575 dprintf(CRITICAL,"Integer overflow detected in bootimage header fields %u %s\n", __LINE__,__func__);
2576 return -1;
2577 }
2578
2579 /*Check the availability of RAM before reading boot image + max signature length from flash*/
2580 if (target_get_max_flash_size() < (imagesize_actual + page_size))
2581 {
2582 dprintf(CRITICAL, "bootimage size is greater than DDR can hold\n");
2583 return -1;
2584 }
2585
2586 offset = page_size;
2587 /* Read image without signature and header */
2588 if (flash_read(ptn, offset, (void *)(image_addr + offset), imagesize_actual - page_size))
2589 {
2590 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
2591 return -1;
2592 }
2593
2594 dprintf(INFO, "Loading (%s) image (%d): done\n",
2595 (!boot_into_recovery ? "boot" : "recovery"), imagesize_actual);
2596 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
2597
Shashank Mittalcd98d472011-08-02 14:29:24 -07002598 /* Authenticate Kernel */
Deepa Dinamani23b60d42013-06-24 18:10:52 -07002599 if(target_use_signed_kernel() && (!device.is_unlocked))
Shashank Mittalcd98d472011-08-02 14:29:24 -07002600 {
Shashank Mittalcd98d472011-08-02 14:29:24 -07002601 offset = imagesize_actual;
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302602
Shashank Mittalcd98d472011-08-02 14:29:24 -07002603 /* Read signature */
2604 if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
2605 {
2606 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002607 return -1;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002608 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002609
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05302610 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302611 }
2612 offset = page_size;
2613 if(hdr->second_size != 0) {
2614 if (UINT_MAX - offset < second_actual)
2615 {
2616 dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
2617 return -1;
vijay kumar8f53e362015-11-24 13:38:11 +05302618 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302619 offset += second_actual;
2620 /* Second image loading not implemented. */
2621 ASSERT(0);
2622 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302623 /* Move kernel and ramdisk to correct address */
2624 memmove((void*) hdr->kernel_addr, (char*) (image_addr + page_size), hdr->kernel_size);
2625 memmove((void*) hdr->ramdisk_addr, (char*) (image_addr + page_size + kernel_actual), hdr->ramdisk_size);
2626
2627#if DEVICE_TREE
2628 if(dt_size != 0) {
2629
2630 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2631
2632 table = (struct dt_table*) dt_table_offset;
2633
2634 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2635 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2636 return -1;
2637 }
2638
2639 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2640 goes beyound hdr->dt_size*/
2641 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
2642 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2643 return -1;
2644 }
2645
2646 /* Find index of device tree within device tree table */
2647 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2648 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2649 return -1;
2650 }
2651
2652 /* Validate and Read device device tree in the "tags_add */
2653 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size) ||
2654 check_ddr_addr_range_bound(hdr->tags_addr, dt_entry.size))
2655 {
2656 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2657 return -1;
2658 }
2659
2660 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2661 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2662 return -1;
2663 }
2664
2665 /* Ensure we are not overshooting dt_size with the dt_entry selected */
2666 if ((dt_entry.offset + dt_entry.size) > dt_size) {
2667 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2668 return -1;
2669 }
2670
2671 best_match_dt_addr = (unsigned char *)table + dt_entry.offset;
2672 dtb_size = dt_entry.size;
2673 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Vivek Kumar07bd0862018-04-10 14:19:23 +05302674
2675 } else {
2676 /* Validate the tags_addr */
2677 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2678 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
2679 {
2680 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2681 return -1;
2682 }
2683 /*
2684 * If appended dev tree is found, update the atags with
2685 * memory address to the DTB appended location on RAM.
2686 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302687 *
2688 * Make sure everything from scratch address is read before next step!
2689 * In case of dtbo, this API is going to read dtbo on scratch.
Vivek Kumar07bd0862018-04-10 14:19:23 +05302690 */
2691 void *dtb = NULL;
2692 dtb = dev_tree_appended((void*)(image_addr + page_size ),hdr->kernel_size, dtb_offset, (void *)hdr->tags_addr);
2693 if (!dtb) {
2694 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
2695 return -1;
2696 }
2697 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302698#endif
2699 if(target_use_signed_kernel() && (!device.is_unlocked))
2700 {
Shashank Mittal162244e2011-08-08 19:01:25 -07002701 /* Make sure everything from scratch address is read before next step!*/
Shashank Mittala0032282011-08-26 14:50:11 -07002702 if(device.is_tampered)
Shashank Mittal162244e2011-08-08 19:01:25 -07002703 {
2704 write_device_info_flash(&device);
2705 }
Channagoud Kadabi5c86fe32012-02-16 10:58:48 +05302706#if USE_PCOM_SECBOOT
2707 set_tamper_flag(device.is_tampered);
2708#endif
Shashank Mittalcd98d472011-08-02 14:29:24 -07002709 }
David Ng183a7422009-12-07 14:55:21 -08002710continue_boot:
Dima Zavin214cc642009-01-26 11:16:21 -08002711
Dima Zavin214cc642009-01-26 11:16:21 -08002712 /* TODO: create/pass atags to kernel */
2713
Ajay Dudanie28a6072011-07-01 13:59:46 -07002714 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002715 (const char *)hdr->cmdline, board_machtype(),
Dima Zavin214cc642009-01-26 11:16:21 -08002716 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2717
2718 return 0;
2719}
Brian Swetland9c4c0752009-01-25 16:23:50 -08002720
Shashank Mittal162244e2011-08-08 19:01:25 -07002721void write_device_info_mmc(device_info *dev)
2722{
Shashank Mittal162244e2011-08-08 19:01:25 -07002723 unsigned long long ptn = 0;
2724 unsigned long long size;
2725 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002726 uint8_t lun = 0;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002727 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302728 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002729
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002730 if (devinfo_present)
2731 index = partition_get_index("devinfo");
2732 else
2733 index = partition_get_index("aboot");
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002734
Shashank Mittal162244e2011-08-08 19:01:25 -07002735 ptn = partition_get_offset(index);
2736 if(ptn == 0)
2737 {
2738 return;
2739 }
2740
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002741 lun = partition_get_lun(index);
2742 mmc_set_lun(lun);
2743
Shashank Mittal162244e2011-08-08 19:01:25 -07002744 size = partition_get_size(index);
2745
Mayank Groverddd348d2018-01-23 14:07:09 +05302746 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2747 mmc_blocksize_mask);
2748 if (device_info_sz == UINT_MAX)
2749 {
2750 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2751 return;
2752 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002753
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002754 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302755 ret = mmc_write(ptn, device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002756 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302757 ret = mmc_write((ptn + size - device_info_sz), device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002758 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002759 {
2760 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002761 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002762 }
2763}
2764
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002765void read_device_info_mmc(struct device_info *info)
Shashank Mittal162244e2011-08-08 19:01:25 -07002766{
Shashank Mittal162244e2011-08-08 19:01:25 -07002767 unsigned long long ptn = 0;
2768 unsigned long long size;
2769 int index = INVALID_PTN;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002770 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302771 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002772
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002773 if ((index = partition_get_index("devinfo")) < 0)
2774 {
2775 devinfo_present = false;
2776 index = partition_get_index("aboot");
2777 }
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002778
Shashank Mittal162244e2011-08-08 19:01:25 -07002779 ptn = partition_get_offset(index);
2780 if(ptn == 0)
2781 {
2782 return;
2783 }
2784
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002785 mmc_set_lun(partition_get_lun(index));
2786
Shashank Mittal162244e2011-08-08 19:01:25 -07002787 size = partition_get_size(index);
2788
Mayank Groverddd348d2018-01-23 14:07:09 +05302789 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2790 mmc_blocksize_mask);
2791 if (device_info_sz == UINT_MAX)
2792 {
2793 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2794 return;
2795 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002796
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002797 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302798 ret = mmc_read(ptn, (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002799 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302800 ret = mmc_read((ptn + size - device_info_sz), (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002801 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002802 {
2803 dprintf(CRITICAL, "ERROR: Cannot read device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002804 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002805 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002806}
2807
tracychui9d60fc52020-06-05 17:31:38 +08002808#if defined(ENABLE_PRODINFO_ACCESS)
2809void write_prod_info_mmc(prod_info *dev)
2810{
2811 unsigned long long ptn = 0;
2812 unsigned long long size;
2813 int index = INVALID_PTN;
2814 uint32_t blocksize;
2815 uint8_t lun = 0;
2816 uint32_t ret = 0;
2817
2818 if (prodinfo_present)
2819 index = partition_get_index("prodinfo");
2820 else
2821 index = partition_get_index("aboot");
2822
2823 ptn = partition_get_offset(index);
2824 if(ptn == 0)
2825 {
2826 return;
2827 }
2828
2829 lun = partition_get_lun(index);
2830 mmc_set_lun(lun);
2831
2832 size = partition_get_size(index);
2833
2834 blocksize = mmc_get_device_blocksize();
2835
2836 if (prodinfo_present)
2837 ret = mmc_write(ptn, blocksize, (void *)prodinfo_buf);
2838 else
2839 ret = mmc_write((ptn + size - blocksize), blocksize, (void *)prodinfo_buf);
2840 if (ret)
2841 {
2842 dprintf(CRITICAL, "ERROR: Cannot write prod info\n");
2843 ASSERT(0);
2844 }
2845}
2846
2847void read_prod_info_mmc(struct prod_info *info)
2848{
2849 unsigned long long ptn = 0;
2850 unsigned long long size;
2851 int index = INVALID_PTN;
2852 uint32_t blocksize;
2853 uint32_t ret = 0;
2854
2855 if ((index = partition_get_index("prodinfo")) < 0)
2856 {
2857 prodinfo_present = false;
2858 index = partition_get_index("aboot");
2859 }
2860
2861 ptn = partition_get_offset(index);
2862 if(ptn == 0)
2863 {
2864 return;
2865 }
2866
2867 mmc_set_lun(partition_get_lun(index));
2868
2869 size = partition_get_size(index);
2870
2871 blocksize = mmc_get_device_blocksize();
2872
2873 if (prodinfo_present)
2874 ret = mmc_read(ptn, (void *)prodinfo_buf, blocksize);
2875 else
2876 ret = mmc_read((ptn + size - blocksize), (void *)prodinfo_buf, blocksize);
2877 if (ret)
2878 {
2879 dprintf(CRITICAL, "ERROR: Cannot read prod info\n");
2880 ASSERT(0);
2881 }
2882}
2883#endif
2884
Shashank Mittal162244e2011-08-08 19:01:25 -07002885void write_device_info_flash(device_info *dev)
2886{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002887 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002888 struct ptentry *ptn;
2889 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002890 if(info == NULL)
2891 {
2892 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2893 ASSERT(0);
2894 }
2895 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002896 ptable = flash_get_ptable();
2897 if (ptable == NULL)
2898 {
2899 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2900 return;
2901 }
2902
2903 ptn = ptable_find(ptable, "devinfo");
2904 if (ptn == NULL)
2905 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002906 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002907 return;
2908 }
2909
Mayank Groverdedbc892017-10-24 13:41:34 +05302910 memset(info, 0, BOOT_IMG_MAX_PAGE_SIZE);
Shashank Mittal162244e2011-08-08 19:01:25 -07002911 memcpy(info, dev, sizeof(device_info));
2912
2913 if (flash_write(ptn, 0, (void *)info_buf, page_size))
2914 {
2915 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2916 return;
2917 }
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002918 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002919}
2920
vijay kumarc65876c2015-04-24 13:29:16 +05302921static int read_allow_oem_unlock(device_info *dev)
2922{
vijay kumarc65876c2015-04-24 13:29:16 +05302923 unsigned offset;
2924 int index;
2925 unsigned long long ptn;
2926 unsigned long long ptn_size;
2927 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002928 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302929
vijay kumarca2e6812015-07-08 20:28:25 +05302930 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302931 if (index == INVALID_PTN)
2932 {
vijay kumarca2e6812015-07-08 20:28:25 +05302933 index = partition_get_index(frp_ptns[1]);
2934 if (index == INVALID_PTN)
2935 {
2936 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2937 return -1;
2938 }
vijay kumarc65876c2015-04-24 13:29:16 +05302939 }
2940
2941 ptn = partition_get_offset(index);
2942 ptn_size = partition_get_size(index);
2943 offset = ptn_size - blocksize;
2944
Mayank Grover48860402016-11-29 12:34:53 +05302945 /* Set Lun for partition */
2946 mmc_set_lun(partition_get_lun(index));
2947
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002948 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302949 {
2950 dprintf(CRITICAL, "Reading MMC failed\n");
2951 return -1;
2952 }
2953
2954 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2955 is_allow_unlock = buf[blocksize-1] & 0x01;
2956 return 0;
2957}
2958
2959static int write_allow_oem_unlock(bool allow_unlock)
2960{
vijay kumarc65876c2015-04-24 13:29:16 +05302961 unsigned offset;
vijay kumarc65876c2015-04-24 13:29:16 +05302962 int index;
2963 unsigned long long ptn;
2964 unsigned long long ptn_size;
2965 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002966 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302967
vijay kumarca2e6812015-07-08 20:28:25 +05302968 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302969 if (index == INVALID_PTN)
2970 {
vijay kumarca2e6812015-07-08 20:28:25 +05302971 index = partition_get_index(frp_ptns[1]);
2972 if (index == INVALID_PTN)
2973 {
2974 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2975 return -1;
2976 }
vijay kumarc65876c2015-04-24 13:29:16 +05302977 }
2978
2979 ptn = partition_get_offset(index);
2980 ptn_size = partition_get_size(index);
2981 offset = ptn_size - blocksize;
Mayank Grover48860402016-11-29 12:34:53 +05302982 mmc_set_lun(partition_get_lun(index));
vijay kumarc65876c2015-04-24 13:29:16 +05302983
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002984 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302985 {
2986 dprintf(CRITICAL, "Reading MMC failed\n");
2987 return -1;
2988 }
2989
2990 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2991 buf[blocksize-1] = allow_unlock;
2992 if (mmc_write(ptn + offset, blocksize, buf))
2993 {
2994 dprintf(CRITICAL, "Writing MMC failed\n");
2995 return -1;
2996 }
2997
2998 return 0;
2999}
3000
Shashank Mittal162244e2011-08-08 19:01:25 -07003001void read_device_info_flash(device_info *dev)
3002{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003003 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07003004 struct ptentry *ptn;
3005 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003006 if(info == NULL)
3007 {
3008 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
3009 ASSERT(0);
3010 }
3011 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07003012 ptable = flash_get_ptable();
3013 if (ptable == NULL)
3014 {
3015 dprintf(CRITICAL, "ERROR: Partition table not found\n");
3016 return;
3017 }
3018
3019 ptn = ptable_find(ptable, "devinfo");
3020 if (ptn == NULL)
3021 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07003022 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07003023 return;
3024 }
3025
3026 if (flash_read(ptn, 0, (void *)info_buf, page_size))
3027 {
3028 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
3029 return;
3030 }
3031
3032 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
3033 {
Shashank Mittal162244e2011-08-08 19:01:25 -07003034 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
3035 info->is_unlocked = 0;
Shashank Mittala0032282011-08-26 14:50:11 -07003036 info->is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07003037 write_device_info_flash(info);
3038 }
3039 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003040 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07003041}
3042
3043void write_device_info(device_info *dev)
3044{
3045 if(target_is_emmc_boot())
3046 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003047 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
3048 if(info == NULL)
3049 {
3050 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
3051 ASSERT(0);
3052 }
3053 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003054 memcpy(info, dev, sizeof(struct device_info));
3055
3056#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05303057 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303058 is_secure_boot_enable()) {
3059 if((write_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
3060 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07003061 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07003062 else
3063 write_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003064#else
3065 write_device_info_mmc(info);
3066#endif
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003067 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07003068 }
3069 else
3070 {
3071 write_device_info_flash(dev);
3072 }
3073}
3074
Monika Singh94316462018-03-15 18:39:01 +05303075int read_rollback_index(uint32_t loc, uint64_t *roll_back_index)
3076{
3077 if (!devinfo_present) {
3078 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3079 return -EINVAL;
3080 }
3081 if (loc >= ARRAY_SIZE(device.rollback_index)) {
3082 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
3083 __func__, loc, ARRAY_SIZE(device.rollback_index));
3084 ASSERT(0);
3085 }
3086
3087 *roll_back_index = device.rollback_index[loc];
3088 return 0;
3089}
3090
3091int write_rollback_index(uint32_t loc, uint64_t roll_back_index)
3092{
3093 if (!devinfo_present) {
3094 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3095 return -EINVAL;
3096 }
3097 if (loc >= ARRAY_SIZE(device.rollback_index)) {
3098 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
3099 __func__, loc, ARRAY_SIZE(device.rollback_index));
3100 ASSERT(0);
3101 }
3102
3103 device.rollback_index[loc] = roll_back_index;
3104 write_device_info(&device);
3105 return 0;
3106}
3107
Monika Singhb0fad822018-03-15 18:50:55 +05303108int store_userkey(uint8_t *user_key, uint32_t user_key_size)
3109{
3110 if (!devinfo_present) {
3111 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3112 return -EINVAL;
3113 }
3114
3115 if (user_key_size > ARRAY_SIZE(device.user_public_key)) {
3116 dprintf(CRITICAL, "StoreUserKey, UserKeySize too large!\n");
3117 return -ENODEV;
3118 }
3119
3120 memcpy(device.user_public_key, user_key, user_key_size);
3121 device.user_public_key_length = user_key_size;
3122 write_device_info(&device);
3123 return 0;
3124}
3125
3126int erase_userkey()
3127{
3128 if (!devinfo_present) {
3129 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3130 return -EINVAL;
3131 }
3132 memset(device.user_public_key, 0, ARRAY_SIZE(device.user_public_key));
3133 device.user_public_key_length = 0;
3134 write_device_info(&device);
3135 return 0;
3136}
3137
3138int get_userkey(uint8_t **user_key, uint32_t *user_key_size)
3139{
3140 if (!devinfo_present) {
3141 dprintf(CRITICAL, "DeviceInfo not initalized \n");
3142 return -EINVAL;
3143 }
3144 *user_key = device.user_public_key;
3145 *user_key_size = device.user_public_key_length;
3146 return 0;
3147}
3148
Shashank Mittal162244e2011-08-08 19:01:25 -07003149void read_device_info(device_info *dev)
3150{
3151 if(target_is_emmc_boot())
3152 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003153 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
3154 if(info == NULL)
3155 {
3156 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
3157 ASSERT(0);
3158 }
3159 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003160
3161#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05303162 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303163 is_secure_boot_enable()) {
3164 if((read_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
3165 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07003166 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07003167 else
3168 read_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003169#else
3170 read_device_info_mmc(info);
3171#endif
3172
3173 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
3174 {
3175 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
lijuang511a2b52015-08-14 20:50:51 +08003176 if (is_secure_boot_enable()) {
Channagoud Kadabi05f78ba2015-07-06 11:58:14 -07003177 info->is_unlocked = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05303178#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303179 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303180 info->is_unlock_critical = 0;
Parth Dixitddbc7352015-10-18 03:13:31 +05303181#endif
lijuang511a2b52015-08-14 20:50:51 +08003182 } else {
Channagoud Kadabi2fda4092015-07-07 13:34:11 -07003183 info->is_unlocked = 1;
Monika Singh292b3e92018-03-17 22:40:23 +05303184#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303185 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303186 info->is_unlock_critical = 1;
Parth Dixitddbc7352015-10-18 03:13:31 +05303187#endif
lijuang511a2b52015-08-14 20:50:51 +08003188 }
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003189 info->is_tampered = 0;
3190 info->charger_screen_enabled = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05303191#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303192 if (VB_M <= target_get_vb_version())
Monika Singh1c71a1c2019-12-03 12:12:48 +05303193 {
Mayank Grover889be1b2017-09-12 20:12:23 +05303194 info->verity_mode = 1; //enforcing by default
Monika Singh1c71a1c2019-12-03 12:12:48 +05303195 info->user_public_key_length = 0;
3196 memset(info->rollback_index, 0, sizeof(info->rollback_index));
3197 memset(info->user_public_key, 0, sizeof(info->user_public_key));
3198 }
Parth Dixitddbc7352015-10-18 03:13:31 +05303199#endif
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003200 write_device_info(info);
3201 }
jessicatseng8e7644c2020-04-22 11:13:20 +08003202
3203 info->charger_screen_enabled = 1;
3204 write_device_info(info);
3205
Channagoud Kadabi036c6052015-02-09 15:19:59 -08003206 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07003207 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07003208 }
3209 else
3210 {
3211 read_device_info_flash(dev);
3212 }
3213}
tracychui9d60fc52020-06-05 17:31:38 +08003214#if defined(ENABLE_PRODINFO_ACCESS)
3215void write_prod_info(prod_info *dev)
3216{
3217 if(target_is_emmc_boot())
3218 {
3219 struct prod_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
3220 if(info == NULL)
3221 {
3222 dprintf(CRITICAL, "Failed to allocate memory for prod info struct\n");
3223 ASSERT(0);
3224 }
3225 prodinfo_buf = info;
3226 memcpy(info, dev, sizeof(struct prod_info));
3227
3228 write_prod_info_mmc(info);
3229 free(info);
3230 }
3231}
3232
3233void read_prod_info(prod_info *dev)
3234{
3235 if(target_is_emmc_boot())
3236 {
3237 struct prod_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
3238 if(info == NULL)
3239 {
3240 dprintf(CRITICAL, "Failed to allocate memory for prod info struct\n");
3241 ASSERT(0);
3242 }
3243 prodinfo_buf = info;
3244
3245 read_prod_info_mmc(info);
3246
3247 if (memcmp(info->magic, PRODINFO_MAGIC, PRODINFO_MAGIC_SIZE))
3248 {
3249 memcpy(info->magic, PRODINFO_MAGIC, PRODINFO_MAGIC_SIZE);
3250 memcpy(info->isn, "No_Serial_Number", PRODINFO_MAX_ISN_LEN);
3251 memcpy(info->ssn, "No_Custer_Serial_Number", PRODINFO_MAX_SSN_LEN);
3252 info->is_adb_enabled = 0;
3253 write_prod_info(info);
3254 }
3255 memcpy(dev, info, sizeof(prod_info));
3256 free(info);
3257 }
3258}
3259#endif
Shashank Mittal162244e2011-08-08 19:01:25 -07003260
3261void reset_device_info()
3262{
3263 dprintf(ALWAYS, "reset_device_info called.");
Shashank Mittala0032282011-08-26 14:50:11 -07003264 device.is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07003265 write_device_info(&device);
3266}
3267
3268void set_device_root()
3269{
3270 dprintf(ALWAYS, "set_device_root called.");
Shashank Mittala0032282011-08-26 14:50:11 -07003271 device.is_tampered = 1;
Shashank Mittal162244e2011-08-08 19:01:25 -07003272 write_device_info(&device);
3273}
3274
lijuang4ece1e72015-08-14 21:02:36 +08003275/* set device unlock value
3276 * Must check FRP before call this function
3277 * Need to wipe data when unlock status changed
3278 * type 0: oem unlock
3279 * type 1: unlock critical
3280 * status 0: unlock as false
3281 * status 1: lock as true
3282 */
3283void set_device_unlock_value(int type, bool status)
lijuang21f12f52015-08-22 16:22:19 +08003284{
lijuang4ece1e72015-08-14 21:02:36 +08003285 if (type == UNLOCK)
3286 device.is_unlocked = status;
Monika Singh292b3e92018-03-17 22:40:23 +05303287#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303288 else if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303289 type == UNLOCK_CRITICAL)
3290 device.is_unlock_critical = status;
Parth Dixitddbc7352015-10-18 03:13:31 +05303291#endif
lijuang4ece1e72015-08-14 21:02:36 +08003292 write_device_info(&device);
3293}
3294
3295static void set_device_unlock(int type, bool status)
3296{
3297 int is_unlocked = -1;
3298 char response[MAX_RSP_SIZE];
3299
3300 /* check device unlock status if it is as expected */
3301 if (type == UNLOCK)
3302 is_unlocked = device.is_unlocked;
Monika Singh292b3e92018-03-17 22:40:23 +05303303#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303304 if(VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303305 type == UNLOCK_CRITICAL)
3306 {
3307 is_unlocked = device.is_unlock_critical;
3308 }
Parth Dixitddbc7352015-10-18 03:13:31 +05303309#endif
lijuang4ece1e72015-08-14 21:02:36 +08003310 if (is_unlocked == status) {
3311 snprintf(response, sizeof(response), "\tDevice already : %s", (status ? "unlocked!" : "locked!"));
3312 fastboot_info(response);
3313 fastboot_okay("");
3314 return;
3315 }
3316
3317 /* status is true, it means to unlock device */
lijuang07c5d6e2018-04-23 18:32:13 +08003318 if (status && !is_allow_unlock) {
3319 fastboot_fail("oem unlock is not allowed");
3320 return;
3321 }
lijuang21f12f52015-08-22 16:22:19 +08003322
ericlin4e397c42020-04-29 14:14:24 +08003323 if(target_build_variant_user()){
lijuang4ece1e72015-08-14 21:02:36 +08003324#if FBCON_DISPLAY_MSG
lijuang07c5d6e2018-04-23 18:32:13 +08003325 display_unlock_menu(type, status);
3326 fastboot_okay("");
3327 return;
lijuang4ece1e72015-08-14 21:02:36 +08003328#else
lijuang07c5d6e2018-04-23 18:32:13 +08003329 if (status && type == UNLOCK) {
3330 fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
3331 return;
lijuang21f12f52015-08-22 16:22:19 +08003332 }
lijuang07c5d6e2018-04-23 18:32:13 +08003333#endif
ericlin4e397c42020-04-29 14:14:24 +08003334 }
lijuang4ece1e72015-08-14 21:02:36 +08003335
3336 set_device_unlock_value(type, status);
3337
3338 /* wipe data */
3339 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05303340 memset(&msg, 0, sizeof(msg));
lijuang4ece1e72015-08-14 21:02:36 +08003341 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
3342 write_misc(0, &msg, sizeof(msg));
3343
3344 fastboot_okay("");
ericlin4e397c42020-04-29 14:14:24 +08003345 //reboot_device(RECOVERY_MODE);
lijuang21f12f52015-08-22 16:22:19 +08003346}
3347
lijuang511a2b52015-08-14 20:50:51 +08003348static bool critical_flash_allowed(const char * entry)
3349{
3350 uint32_t i = 0;
3351 if (entry == NULL)
3352 return false;
3353
3354 for (i = 0; i < ARRAY_SIZE(critical_flash_allowed_ptn); i++) {
3355 if(!strcmp(entry, critical_flash_allowed_ptn[i]))
3356 return true;
3357 }
3358 return false;
Matthew Qin271927e2015-03-31 22:07:07 -04003359}
3360
3361#if DEVICE_TREE
Amol Jadicb524072012-08-09 16:40:18 -07003362int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
3363{
3364 uint32 dt_image_offset = 0;
Amol Jadicb524072012-08-09 16:40:18 -07003365 uint32_t n;
Monika Singh292b3e92018-03-17 22:40:23 +05303366 struct dt_table *table = NULL;
Amol Jadicb524072012-08-09 16:40:18 -07003367 struct dt_entry dt_entry;
Monika Singh292b3e92018-03-17 22:40:23 +05303368 uint32_t dt_hdr_size = 0;
Amol Jadicb524072012-08-09 16:40:18 -07003369 unsigned int compressed_size = 0;
3370 unsigned int dtb_size = 0;
3371 unsigned int out_avai_len = 0;
3372 unsigned char *out_addr = NULL;
3373 unsigned char *best_match_dt_addr = NULL;
3374 int rc;
3375
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303376 boot_img_hdr *hdr = (boot_img_hdr *) (boot_image_start);
Amol Jadicb524072012-08-09 16:40:18 -07003377
Parth Dixit4097b622016-03-15 14:42:27 +05303378#ifndef OSVERSION_IN_BOOTIMAGE
3379 dt_size = hdr->dt_size;
3380#endif
3381
3382 if(dt_size != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07003383 /* add kernel offset */
3384 dt_image_offset += page_size;
3385 n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
3386 dt_image_offset += n;
3387
3388 /* add ramdisk offset */
3389 n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
3390 dt_image_offset += n;
3391
3392 /* add second offset */
3393 if(hdr->second_size != 0) {
3394 n = ROUND_TO_PAGE(hdr->second_size, page_mask);
3395 dt_image_offset += n;
3396 }
3397
3398 /* offset now point to start of dt.img */
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07003399 table = (struct dt_table*)(boot_image_start + dt_image_offset);
Amol Jadicb524072012-08-09 16:40:18 -07003400
Deepa Dinamani19648b42013-09-05 17:05:55 -07003401 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07003402 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
3403 return -1;
3404 }
P.V. Phani Kumar82916762016-03-09 09:20:19 +05303405
3406 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
3407 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05303408 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05303409 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
3410 return -1;
3411 }
3412
Joel Kingaa335dc2013-06-03 16:11:08 -07003413 /* Find index of device tree within device tree table */
3414 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Amol Jadicb524072012-08-09 16:40:18 -07003415 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
3416 return -1;
3417 }
3418
Matthew Qin271927e2015-03-31 22:07:07 -04003419 best_match_dt_addr = (unsigned char *)boot_image_start + dt_image_offset + dt_entry.offset;
3420 if (is_gzip_package(best_match_dt_addr, dt_entry.size))
3421 {
3422 out_addr = (unsigned char *)target_get_scratch_address() + scratch_offset;
3423 out_avai_len = target_get_max_flash_size() - scratch_offset;
Matthew Qin0b15b322015-05-19 05:20:54 -04003424 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003425 rc = decompress(best_match_dt_addr,
3426 dt_entry.size, out_addr, out_avai_len,
3427 &compressed_size, &dtb_size);
3428 if (rc)
3429 {
Matthew Qin0b15b322015-05-19 05:20:54 -04003430 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003431 ASSERT(0);
3432 }
3433
Matthew Qin0b15b322015-05-19 05:20:54 -04003434 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003435 best_match_dt_addr = out_addr;
3436 } else {
3437 dtb_size = dt_entry.size;
3438 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003439 /* Validate and Read device device tree in the "tags_add */
Mayank Grovere559cec2017-10-17 15:12:03 +05303440 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
3441 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003442 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303443 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003444 return -1;
3445 }
3446
Amol Jadicb524072012-08-09 16:40:18 -07003447 /* Read device device tree in the "tags_add */
Matthew Qin271927e2015-03-31 22:07:07 -04003448 memmove((void*) hdr->tags_addr, (void *)best_match_dt_addr, dtb_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003449 } else
3450 return -1;
Amol Jadicb524072012-08-09 16:40:18 -07003451
3452 /* Everything looks fine. Return success. */
3453 return 0;
3454}
3455#endif
3456
Brian Swetland9c4c0752009-01-25 16:23:50 -08003457void cmd_boot(const char *arg, void *data, unsigned sz)
3458{
3459 unsigned kernel_actual;
3460 unsigned ramdisk_actual;
Kishor PKd8ddcad2017-07-27 13:53:57 +05303461 unsigned second_actual;
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003462 uint32_t image_actual;
3463 uint32_t dt_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303464 boot_img_hdr *hdr = NULL;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003465 struct kernel64_hdr *kptr = NULL;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003466 char *ptr = ((char*) data);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003467 int ret = 0;
3468 uint8_t dtb_copied = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003469 unsigned int out_len = 0;
3470 unsigned int out_avai_len = 0;
3471 unsigned char *out_addr = NULL;
3472 uint32_t dtb_offset = 0;
3473 unsigned char *kernel_start_addr = NULL;
3474 unsigned int kernel_size = 0;
Matthew Qin271927e2015-03-31 22:07:07 -04003475 unsigned int scratch_offset = 0;
Saranya Chidurab4933332018-10-15 17:30:06 +05303476#if VERIFIED_BOOT_2
3477 void *dtbo_image_buf = NULL;
3478 uint32_t dtbo_image_sz = 0;
3479 void *vbmeta_image_buf = NULL;
3480 uint32_t vbmeta_image_sz = 0;
3481#endif
Monika Singh292b3e92018-03-17 22:40:23 +05303482#if !VERIFIED_BOOT_2
3483 uint32_t sig_actual = 0;
3484 uint32_t sig_size = 0;
3485#ifdef MDTP_SUPPORT
3486 static bool is_mdtp_activated = 0;
3487#endif /* MDTP_SUPPORT */
3488#endif
Matthew Qinbb7923d2015-02-09 10:56:09 +08003489
lijuang2008ff22016-03-07 17:56:27 +08003490#if FBCON_DISPLAY_MSG
3491 /* Exit keys' detection thread firstly */
3492 exit_menu_keys_detection();
3493#endif
3494
Monika Singh292b3e92018-03-17 22:40:23 +05303495#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi6d5375e2015-06-23 17:15:42 -07003496 if(target_build_variant_user() && !device.is_unlocked)
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003497 {
3498 fastboot_fail("unlock device to use this command");
lijuang2008ff22016-03-07 17:56:27 +08003499 goto boot_failed;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003500 }
3501#endif
3502
Brian Swetland9c4c0752009-01-25 16:23:50 -08003503 if (sz < sizeof(hdr)) {
3504 fastboot_fail("invalid bootimage header");
lijuang2008ff22016-03-07 17:56:27 +08003505 goto boot_failed;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003506 }
3507
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303508 hdr = (boot_img_hdr *)data;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003509
3510 /* ensure commandline is terminated */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003511 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003512
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003513 if(target_is_emmc_boot() && hdr->page_size) {
3514 page_size = hdr->page_size;
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07003515 page_mask = page_size - 1;
3516 }
3517
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003518 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
3519 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303520 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003521#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05303522#ifndef OSVERSION_IN_BOOTIMAGE
3523 dt_size = hdr->dt_size;
3524#endif
3525 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003526#endif
3527
3528 image_actual = ADD_OF(page_size, kernel_actual);
3529 image_actual = ADD_OF(image_actual, ramdisk_actual);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303530 image_actual = ADD_OF(image_actual, second_actual);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003531 image_actual = ADD_OF(image_actual, dt_actual);
3532
Kishor PK5134b332017-05-09 17:50:08 +05303533 /* Checking to prevent oob access in read_der_message_length */
3534 if (image_actual > sz) {
3535 fastboot_fail("bootimage header fields are invalid");
3536 goto boot_failed;
3537 }
Saranya Chidurab4933332018-10-15 17:30:06 +05303538
Monika Singh292b3e92018-03-17 22:40:23 +05303539#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05303540 /* Pass size of boot partition, as imgsize, to avoid
3541 read fewer bytes error */
3542 image_actual = partition_get_size(partition_get_index("boot"));
Saranya Chidurab4933332018-10-15 17:30:06 +05303543
3544 /* load and validate dtbo partition */
3545 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
3546
3547 /* load vbmeta partition */
3548 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
3549
Monika Singh292b3e92018-03-17 22:40:23 +05303550 memset(&info, 0, sizeof(bootinfo));
Saranya Chidurab4933332018-10-15 17:30:06 +05303551
3552 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(data);
3553 info.images[IMG_BOOT].imgsize = image_actual;
3554 info.images[IMG_BOOT].name = "boot";
3555 ++info.num_loaded_images;
3556
3557 /* Pass loaded dtbo image */
3558 if (dtbo_image_buf != NULL) {
3559 info.images[IMG_DTBO].image_buffer = SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
3560 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
3561 info.images[IMG_DTBO].name = "dtbo";
3562 ++info.num_loaded_images;
3563 }
3564
3565 /* Pass loaded vbmeta image */
3566 if (vbmeta_image_buf != NULL) {
3567 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
3568 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
3569 info.images[IMG_VBMETA].name = "vbmeta";
3570 ++info.num_loaded_images;
3571 }
3572
Monika Singh292b3e92018-03-17 22:40:23 +05303573 info.multi_slot_boot = partition_multislot_is_supported();
3574 if (load_image_and_auth(&info))
3575 goto boot_failed;
3576 vbcmdline = info.vbcmdline;
Saranya Chidurab4933332018-10-15 17:30:06 +05303577
3578 /* Free the buffer allocated to vbmeta post verification */
3579 if (vbmeta_image_buf != NULL) {
3580 free(vbmeta_image_buf);
3581 --info.num_loaded_images;
3582 }
Monika Singh292b3e92018-03-17 22:40:23 +05303583#else
Kishor PK5134b332017-05-09 17:50:08 +05303584 sig_size = sz - image_actual;
3585
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303586 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Monika Singh292b3e92018-03-17 22:40:23 +05303587 unsigned chk;
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303588 /* Calculate the signature length from boot image */
3589 sig_actual = read_der_message_length(
Kishor PK5134b332017-05-09 17:50:08 +05303590 (unsigned char*)(data + image_actual), sig_size);
Monika Singh292b3e92018-03-17 22:40:23 +05303591 chk = ADD_OF(image_actual, sig_actual);
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003592
Monika Singh292b3e92018-03-17 22:40:23 +05303593 if (chk > sz) {
Kishor PK5134b332017-05-09 17:50:08 +05303594 fastboot_fail("bootimage header fields are invalid");
3595 goto boot_failed;
3596 }
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003597 }
3598
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003599 // Initialize boot state before trying to verify boot.img
3600#if VERIFIED_BOOT
Channagoud Kadabi699466e2015-11-03 12:37:42 -08003601 boot_verifier_init();
Mayank Groverb337e932017-01-18 20:00:40 +05303602#endif
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003603 /* Handle overflow if the input image size is greater than
3604 * boot image buffer can hold
3605 */
Monika Singh292b3e92018-03-17 22:40:23 +05303606 if ((target_get_max_flash_size() - page_size) < image_actual)
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003607 {
3608 fastboot_fail("booimage: size is greater than boot image buffer can hold");
lijuang2008ff22016-03-07 17:56:27 +08003609 goto boot_failed;
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003610 }
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003611
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003612 /* Verify the boot image
3613 * device & page_size are initialized in aboot_init
3614 */
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003615 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003616 /* Pass size excluding signature size, otherwise we would try to
3617 * access signature beyond its length
3618 */
Monika Singh292b3e92018-03-17 22:40:23 +05303619 verify_signed_bootimg((uint32_t)data, image_actual);
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003620 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003621#ifdef MDTP_SUPPORT
3622 else
3623 {
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003624 /* fastboot boot is not allowed when MDTP is activated */
Amit Blay4aa292f2015-04-28 21:55:59 +03003625 mdtp_ext_partition_verification_t ext_partition;
Amit Blay8a510302015-08-17 09:20:01 +03003626
3627 if (!is_mdtp_activated) {
3628 ext_partition.partition = MDTP_PARTITION_NONE;
3629 mdtp_fwlock_verify_lock(&ext_partition);
3630 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003631 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003632
Amir Kotzer7c768c02016-04-13 09:08:05 +03003633 /* If mdtp state cannot be validate, block fastboot boot*/
3634 if(mdtp_activated(&is_mdtp_activated)){
3635 dprintf(CRITICAL, "mdtp_activated cannot validate state.\n");
3636 dprintf(CRITICAL, "Can not proceed with fastboot boot command.\n");
3637 goto boot_failed;
3638 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003639 if(is_mdtp_activated){
3640 dprintf(CRITICAL, "fastboot boot command is not available.\n");
lijuang2008ff22016-03-07 17:56:27 +08003641 goto boot_failed;
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003642 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003643#endif /* MDTP_SUPPORT */
Monika Singh292b3e92018-03-17 22:40:23 +05303644#endif /* VERIFIED_BOOT_2 else */
Amit Blay4aa292f2015-04-28 21:55:59 +03003645
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003646#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05303647 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303648 {
3649 /* set boot and system versions. */
3650 set_os_version((unsigned char *)data);
3651 // send root of trust
3652 if(!send_rot_command((uint32_t)device.is_unlocked))
3653 ASSERT(0);
3654 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05303655#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003656 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08003657 * Check if the kernel image is a gzip package. If yes, need to decompress it.
3658 * If not, continue booting.
3659 */
3660 if (is_gzip_package((unsigned char *)(data + page_size), hdr->kernel_size))
3661 {
3662 out_addr = (unsigned char *)target_get_scratch_address();
3663 out_addr = (unsigned char *)(out_addr + image_actual + page_size);
3664 out_avai_len = target_get_max_flash_size() - image_actual - page_size;
Saranya Chidurab4933332018-10-15 17:30:06 +05303665#if VERIFIED_BOOT_2
3666 if (dtbo_image_sz)
3667 out_avai_len -= DTBO_IMG_BUF;
3668#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04003669 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003670 ret = decompress((unsigned char *)(ptr + page_size),
3671 hdr->kernel_size, out_addr, out_avai_len,
3672 &dtb_offset, &out_len);
3673 if (ret)
3674 {
Matthew Qin0b15b322015-05-19 05:20:54 -04003675 dprintf(CRITICAL, "decompressing image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003676 ASSERT(0);
3677 }
3678
Matthew Qin0b15b322015-05-19 05:20:54 -04003679 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003680 kptr = (struct kernel64_hdr *)out_addr;
3681 kernel_start_addr = out_addr;
3682 kernel_size = out_len;
3683 } else {
3684 kptr = (struct kernel64_hdr*)((char *)data + page_size);
3685 kernel_start_addr = (unsigned char *)((char *)data + page_size);
3686 kernel_size = hdr->kernel_size;
3687 }
3688
3689 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003690 * Update the kernel/ramdisk/tags address if the boot image header
3691 * has default values, these default values come from mkbootimg when
3692 * the boot image is flashed using fastboot flash:raw
3693 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08003694 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Dima Zavin3cadfff2013-03-21 14:30:48 -07003695
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003696 /* Get virtual addresses since the hdr saves physical addresses. */
3697 hdr->kernel_addr = VA(hdr->kernel_addr);
3698 hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
3699 hdr->tags_addr = VA(hdr->tags_addr);
Brian Swetland9c4c0752009-01-25 16:23:50 -08003700
Matthew Qinbb7923d2015-02-09 10:56:09 +08003701 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003702 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08003703 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05303704 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
3705 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
3706 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003707 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303708 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003709 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003710 }
3711
Amol Jadicb524072012-08-09 16:40:18 -07003712#if DEVICE_TREE
Matthew Qin271927e2015-03-31 22:07:07 -04003713 scratch_offset = image_actual + page_size + out_len;
Amol Jadicb524072012-08-09 16:40:18 -07003714 /* find correct dtb and copy it to right location */
Matthew Qin271927e2015-03-31 22:07:07 -04003715 ret = copy_dtb(data, scratch_offset);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003716
3717 dtb_copied = !ret ? 1 : 0;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003718#else
Mayank Grovere559cec2017-10-17 15:12:03 +05303719 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
3720 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003721 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303722 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003723 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003724 }
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003725#endif
3726
3727 /* Load ramdisk & kernel */
3728 memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
Matthew Qinbb7923d2015-02-09 10:56:09 +08003729 memmove((void*) hdr->kernel_addr, (char*) (kernel_start_addr), kernel_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003730
3731#if DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05303732 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
3733 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Matthew Qinbb7923d2015-02-09 10:56:09 +08003734 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303735 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003736 goto boot_failed;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003737 }
3738
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003739 /*
3740 * If dtb is not found look for appended DTB in the kernel.
3741 * If appended dev tree is found, update the atags with
3742 * memory address to the DTB appended location on RAM.
3743 * Else update with the atags address in the kernel header
3744 */
3745 if (!dtb_copied) {
3746 void *dtb;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003747 dtb = dev_tree_appended((void*)(ptr + page_size),
3748 hdr->kernel_size, dtb_offset,
Dima Zavine63e5572013-05-03 12:23:06 -07003749 (void *)hdr->tags_addr);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003750 if (!dtb) {
3751 fastboot_fail("dtb not found");
lijuang2008ff22016-03-07 17:56:27 +08003752 goto boot_failed;
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003753 }
Amol Jadicb524072012-08-09 16:40:18 -07003754 }
3755#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08003756
3757 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07003758 fastboot_stop();
Brian Swetland9c4c0752009-01-25 16:23:50 -08003759
Dima Zavin77e41f32013-03-06 16:10:43 -08003760 boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003761 (const char*) hdr->cmdline, board_machtype(),
3762 (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
lijuang2008ff22016-03-07 17:56:27 +08003763
3764 /* fastboot already stop, it's no need to show fastboot menu */
3765 return;
3766boot_failed:
3767#if FBCON_DISPLAY_MSG
3768 /* revert to fastboot menu if boot failed */
3769 display_fastboot_menu();
3770#endif
3771 return;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003772}
3773
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003774void cmd_erase_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08003775{
3776 struct ptentry *ptn;
3777 struct ptable *ptable;
3778
3779 ptable = flash_get_ptable();
3780 if (ptable == NULL) {
3781 fastboot_fail("partition table doesn't exist");
3782 return;
3783 }
3784
3785 ptn = ptable_find(ptable, arg);
3786 if (ptn == NULL) {
3787 fastboot_fail("unknown partition name");
3788 return;
3789 }
3790
Monika Singh292b3e92018-03-17 22:40:23 +05303791 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3792 dprintf(INFO, "erasing avb_custom_key\n");
3793 if (erase_userkey()) {
3794 fastboot_fail("Erasing avb_custom_key failed");
3795 } else {
3796 fastboot_okay("");
3797 }
3798 return;
3799 }
3800
Dima Zavin214cc642009-01-26 11:16:21 -08003801 if (flash_erase(ptn)) {
3802 fastboot_fail("failed to erase partition");
3803 return;
3804 }
3805 fastboot_okay("");
3806}
3807
Bikas Gurungd48bd242010-09-04 19:54:32 -07003808
3809void cmd_erase_mmc(const char *arg, void *data, unsigned sz)
3810{
3811 unsigned long long ptn = 0;
Oliver Wangcee448d2013-10-22 18:40:13 +08003812 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003813 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003814 uint8_t lun = 0;
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303815 char *footer = NULL;
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05303816 char EraseResultStr[MAX_RSP_SIZE] = "";
3817 VirtualAbMergeStatus SnapshotMergeStatus;
Bikas Gurungd48bd242010-09-04 19:54:32 -07003818
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003819#if VERIFIED_BOOT
3820 if(!strcmp(arg, KEYSTORE_PTN_NAME))
3821 {
3822 if(!device.is_unlocked)
3823 {
3824 fastboot_fail("unlock device to erase keystore");
3825 return;
3826 }
3827 }
3828#endif
3829
Kinson Chikf1a43512011-07-14 11:28:39 -07003830 index = partition_get_index(arg);
3831 ptn = partition_get_offset(index);
Oliver Wangcee448d2013-10-22 18:40:13 +08003832 size = partition_get_size(index);
Neeti Desaica8c9602011-10-06 11:40:00 -07003833
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05303834 if (target_virtual_ab_supported()) {
3835 if (CheckVirtualAbCriticalPartition (arg)) {
3836 snprintf(EraseResultStr, MAX_RSP_SIZE,"Erase of %s is not allowed in %s state",
3837 arg, SnapshotMergeState);
3838 fastboot_fail(EraseResultStr);
3839 return;
3840 }
3841 SnapshotMergeStatus = GetSnapshotMergeStatus ();
3842 if (((SnapshotMergeStatus == MERGING) || (SnapshotMergeStatus == SNAPSHOTTED)) &&
3843 !strncmp (arg, "super", strlen ("super"))) {
3844
3845 if(SetSnapshotMergeStatus (CANCELLED))
3846 {
3847 fastboot_fail("Failed to update snapshot state to cancel");
3848 return;
3849 }
3850
3851 //updating fbvar snapshot-merge-state
3852 snprintf(SnapshotMergeState,strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
3853 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
3854 }
3855 }
3856
Monika Singhc4778b72018-05-16 11:16:42 +05303857 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3858 dprintf(INFO, "erasing avb_custom_key\n");
3859 if (erase_userkey()) {
3860 fastboot_fail("Erasing avb_custom_key failed");
3861 } else {
3862 fastboot_okay("");
3863 }
3864 return;
3865 }
3866
Kinson Chikf1a43512011-07-14 11:28:39 -07003867 if(ptn == 0) {
Neeti Desaica8c9602011-10-06 11:40:00 -07003868 fastboot_fail("Partition table doesn't exist\n");
Bikas Gurungd48bd242010-09-04 19:54:32 -07003869 return;
3870 }
Kun Liang2f1601a2013-08-12 16:29:54 +08003871
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003872 lun = partition_get_lun(index);
3873 mmc_set_lun(lun);
3874
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003875 if (platform_boot_dev_isemmc())
3876 {
3877 if (mmc_erase_card(ptn, size)) {
3878 fastboot_fail("failed to erase partition\n");
3879 return;
3880 }
3881 } else {
3882 BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE);
3883 size = partition_get_size(index);
3884 if (size > DEFAULT_ERASE_SIZE)
3885 size = DEFAULT_ERASE_SIZE;
Kun Liang2f1601a2013-08-12 16:29:54 +08003886
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003887 /* Simple inefficient version of erase. Just writing
3888 0 in first several blocks */
3889 if (mmc_write(ptn , size, (unsigned int *)out)) {
3890 fastboot_fail("failed to erase partition");
3891 return;
3892 }
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303893 /*Erase FDE metadata at the userdata footer*/
3894 if(!(strncmp(arg, "userdata", 8)))
3895 {
3896 footer = memalign(CACHE_LINE, FOOTER_SIZE);
3897 memset((void *)footer, 0, FOOTER_SIZE);
3898
3899 size = partition_get_size(index);
3900
3901 if (mmc_write((ptn + size) - FOOTER_SIZE , FOOTER_SIZE, (unsigned int *)footer)) {
3902 fastboot_fail("failed to erase userdata footer");
3903 free(footer);
3904 return;
3905 }
3906 free(footer);
3907 }
Bikas Gurungd48bd242010-09-04 19:54:32 -07003908 }
Monika Singh292b3e92018-03-17 22:40:23 +05303909#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303910 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303911 !(strncmp(arg, "userdata", 8)) &&
3912 send_delete_keys_to_tz())
Sridhar Parasuram32b30662015-07-10 13:33:22 -07003913 ASSERT(0);
3914#endif
Bikas Gurungd48bd242010-09-04 19:54:32 -07003915 fastboot_okay("");
3916}
3917
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003918void cmd_erase(const char *arg, void *data, unsigned sz)
3919{
Monika Singh292b3e92018-03-17 22:40:23 +05303920#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07003921 if (target_build_variant_user())
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003922 {
Sridhar Parasuramc32d07d2015-07-12 10:57:48 -07003923 if(!device.is_unlocked)
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003924 {
Channagoud Kadabi35297672015-06-13 11:09:49 -07003925 fastboot_fail("device is locked. Cannot erase");
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003926 return;
3927 }
3928 }
3929#endif
3930
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003931 if(target_is_emmc_boot())
3932 cmd_erase_mmc(arg, data, sz);
3933 else
3934 cmd_erase_nand(arg, data, sz);
3935}
Bikas Gurungd48bd242010-09-04 19:54:32 -07003936
Mayank Grover11ff9692018-01-11 11:54:49 +05303937/* Get the size from partiton name */
3938static void get_partition_size(const char *arg, char *response)
3939{
3940 uint64_t ptn = 0;
3941 uint64_t size;
3942 int index = INVALID_PTN;
3943
3944 index = partition_get_index(arg);
3945
3946 if (index == INVALID_PTN)
3947 {
3948 dprintf(CRITICAL, "Invalid partition index\n");
3949 return;
3950 }
3951
3952 ptn = partition_get_offset(index);
3953
3954 if(!ptn)
3955 {
3956 dprintf(CRITICAL, "Invalid partition name %s\n", arg);
3957 return;
3958 }
3959
3960 size = partition_get_size(index);
3961
3962 snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size);
3963 return;
3964}
3965
Mayank Grover52cd10a2018-03-15 12:57:54 +05303966/* Function to check partition type of a partition*/
3967static fs_signature_type
3968check_partition_fs_signature(const char *arg)
3969{
3970 fs_signature_type ret = NO_FS;
3971 int index;
3972 unsigned long long ptn;
Mayank Grover399826a2018-08-27 12:15:15 +05303973 char *buffer = memalign(CACHE_LINE, mmc_blocksize);
3974 uint32_t sb_blk_offset = 0;
3975 char *sb_buffer = buffer;
3976
Mayank Grover52cd10a2018-03-15 12:57:54 +05303977 if (!sb_buffer)
3978 {
3979 dprintf(CRITICAL, "ERROR: Failed to allocate buffer for superblock\n");
3980 goto out;
3981 }
3982
3983 /* Read super block */
3984 if ((index = partition_get_index(arg)) < 0)
3985 {
3986 dprintf(CRITICAL, "ERROR: %s() doesn't exsit\n", arg);
3987 goto out;
3988 }
3989 ptn = partition_get_offset(index);
3990 mmc_set_lun(partition_get_lun(index));
Mayank Grover399826a2018-08-27 12:15:15 +05303991 sb_blk_offset = (FS_SUPERBLOCK_OFFSET/mmc_blocksize);
3992
3993 if(mmc_read(ptn + (sb_blk_offset * mmc_blocksize),
Mayank Grover52cd10a2018-03-15 12:57:54 +05303994 (void *)sb_buffer, mmc_blocksize))
3995 {
3996 dprintf(CRITICAL, "ERROR: Failed to read Superblock\n");
3997 goto out;
3998 }
3999
Mayank Grover399826a2018-08-27 12:15:15 +05304000 if (sb_blk_offset == 0)
4001 sb_buffer += FS_SUPERBLOCK_OFFSET;
4002
4003 if (*((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])) == (uint16)EXT_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05304004 {
4005 dprintf(SPEW, "%s() Found EXT FS\n", arg);
4006 ret = EXT_FS_SIGNATURE;
4007 }
Mayank Grover399826a2018-08-27 12:15:15 +05304008 else if (*((uint32 *)(&sb_buffer[F2FS_MAGIC_OFFSET_SB])) == F2FS_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05304009 {
4010 dprintf(SPEW, "%s() Found F2FS FS\n", arg);
4011 ret = EXT_F2FS_SIGNATURE;
4012 }
4013 else
4014 {
4015 dprintf(SPEW, "%s() Reverting to default 0x%x\n",
4016 arg, *((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])));
4017 ret = NO_FS;
4018 }
4019
4020out:
Mayank Grover399826a2018-08-27 12:15:15 +05304021 if(buffer)
4022 free(buffer);
Mayank Grover52cd10a2018-03-15 12:57:54 +05304023 return ret;
4024}
4025
Mayank Groverd38fe012018-03-13 15:33:16 +05304026/* Function to get partition type */
4027static void get_partition_type(const char *arg, char *response)
4028{
4029 uint n = 0;
Mayank Grover52cd10a2018-03-15 12:57:54 +05304030 fs_signature_type fs_signature;
Mayank Groverd38fe012018-03-13 15:33:16 +05304031
4032 if (arg == NULL ||
4033 response == NULL)
4034 {
4035 dprintf(CRITICAL, "Invalid input parameter\n");
4036 return;
4037 }
4038
4039 /* By default copy raw to response */
Mayank Grover0e559042018-04-11 17:49:30 +05304040 strlcpy(response, RAW_STR, MAX_RSP_SIZE);
Mayank Groverd38fe012018-03-13 15:33:16 +05304041
4042 /* Mark partiton type for known paritions only */
4043 for (n=0; n < ARRAY_SIZE(part_type_known); n++)
4044 {
4045 if (!strncmp(part_type_known[n].part_name, arg, strlen(arg)))
4046 {
Mayank Grover52cd10a2018-03-15 12:57:54 +05304047 /* Check partition for FS signature */
4048 fs_signature = check_partition_fs_signature(arg);
4049 switch (fs_signature)
4050 {
4051 case EXT_FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05304052 strlcpy(response, EXT_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05304053 break;
4054 case EXT_F2FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05304055 strlcpy(response, F2FS_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05304056 break;
4057 case NO_FS:
Mayank Grover0e559042018-04-11 17:49:30 +05304058 strlcpy(response, part_type_known[n].type_response, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05304059 }
Mayank Groverd38fe012018-03-13 15:33:16 +05304060 }
4061 }
4062 return;
4063}
4064
Mayank Grover11ff9692018-01-11 11:54:49 +05304065/*
4066 * Publish the partition type & size info
4067 * fastboot getvar will publish the required information.
4068 * fastboot getvar partition_size:<partition_name>: partition size in hex
4069 * fastboot getvar partition_type:<partition_name>: partition type (ext/fat)
4070 */
4071static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
4072{
Mayank Groverd38fe012018-03-13 15:33:16 +05304073 uint8_t i;
Mayank Grover11ff9692018-01-11 11:54:49 +05304074 static bool published = false;
4075 struct partition_entry *ptn_entry =
4076 partition_get_partition_entries();
4077 memset(info, 0, sizeof(struct getvar_partition_info)* num_parts);
4078
4079 for (i = 0; i < num_parts; i++) {
4080 strlcat(info[i].part_name, (const char *)ptn_entry[i].name, MAX_RSP_SIZE);
4081 strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
4082 strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
4083
Mayank Groverd38fe012018-03-13 15:33:16 +05304084 get_partition_type(info[i].part_name, info[i].type_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05304085 get_partition_size(info[i].part_name, info[i].size_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05304086 if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
4087 {
4088 dprintf(CRITICAL, "partition size name truncated\n");
4089 return;
4090 }
4091 if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
4092 {
4093 dprintf(CRITICAL, "partition type name truncated\n");
4094 return;
4095 }
4096
4097 if (!published)
4098 {
4099 /* publish partition size & type info */
4100 fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response);
4101 fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response);
4102 }
4103 }
4104 if (!published)
4105 published = true;
4106}
4107
4108
Ajay Dudani5c761132011-04-07 20:19:04 -07004109void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
Shashank Mittal23b8f422010-04-16 19:27:21 -07004110{
4111 unsigned long long ptn = 0;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07004112 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07004113 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004114 char *token = NULL;
4115 char *pname = NULL;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07004116 char *sp;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004117 uint8_t lun = 0;
4118 bool lun_set = false;
Mayank Grover351a75e2017-05-30 20:06:08 +05304119 int current_active_slot = INVALID;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07004120
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07004121 token = strtok_r((char *)arg, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004122 pname = token;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07004123 token = strtok_r(NULL, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004124 if(token)
4125 {
4126 lun = atoi(token);
4127 mmc_set_lun(lun);
4128 lun_set = true;
4129 }
4130
Mao Jinlong226f33a2014-07-04 17:24:10 +08004131 if (pname)
Greg Grisco6e754772011-06-23 12:19:39 -07004132 {
Channagoud Kadabiad259832015-05-29 11:14:17 -07004133 if (!strncmp(pname, "frp-unlock", strlen("frp-unlock")))
4134 {
4135 if (!aboot_frp_unlock(pname, data, sz))
4136 {
4137 fastboot_info("FRP unlock successful");
4138 fastboot_okay("");
4139 }
4140 else
4141 fastboot_fail("Secret key is invalid, please update the bootloader with secret key");
4142
4143 return;
4144 }
4145
Mao Jinlong226f33a2014-07-04 17:24:10 +08004146 if (!strcmp(pname, "partition"))
4147 {
4148 dprintf(INFO, "Attempt to write partition image.\n");
4149 if (write_partition(sz, (unsigned char *) data)) {
4150 fastboot_fail("failed to write partition");
Greg Grisco6e754772011-06-23 12:19:39 -07004151 return;
4152 }
Mayank Grover11ff9692018-01-11 11:54:49 +05304153 /* Re-publish partition table */
4154 publish_getvar_partition_info(part_info, partition_get_partition_count());
Mayank Grover351a75e2017-05-30 20:06:08 +05304155
4156 /* Rescan partition table to ensure we have multislot support*/
4157 if (partition_scan_for_multislot())
4158 {
4159 current_active_slot = partition_find_active_slot();
4160 dprintf(INFO, "Multislot supported: Slot %s active",
4161 (SUFFIX_SLOT(current_active_slot)));
4162 }
4163 partition_mark_active_slot(current_active_slot);
Greg Grisco6e754772011-06-23 12:19:39 -07004164 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08004165 else
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004166 {
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004167#if VERIFIED_BOOT
4168 if(!strcmp(pname, KEYSTORE_PTN_NAME))
4169 {
4170 if(!device.is_unlocked)
4171 {
4172 fastboot_fail("unlock device to flash keystore");
4173 return;
4174 }
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +05304175 if(!boot_verify_validate_keystore((unsigned char *)data,sz))
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004176 {
4177 fastboot_fail("image is not a keystore file");
4178 return;
4179 }
4180 }
4181#endif
Mao Jinlong226f33a2014-07-04 17:24:10 +08004182 index = partition_get_index(pname);
4183 ptn = partition_get_offset(index);
4184 if(ptn == 0) {
4185 fastboot_fail("partition table doesn't exist");
4186 return;
4187 }
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004188
Mayank Grover351a75e2017-05-30 20:06:08 +05304189 if (!strncmp(pname, "boot", strlen("boot"))
4190 || !strcmp(pname, "recovery"))
4191 {
Ashish Bhimanpalliwar84f7db92020-09-23 11:59:16 +05304192 if ((sz < BOOT_MAGIC_SIZE) || memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Mao Jinlong226f33a2014-07-04 17:24:10 +08004193 fastboot_fail("image is not a boot image");
4194 return;
4195 }
Mayank Grover351a75e2017-05-30 20:06:08 +05304196
4197 /* Reset multislot_partition attributes in case of flashing boot */
4198 if (partition_multislot_is_supported())
4199 {
4200 partition_reset_attributes(index);
4201 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08004202 }
4203
4204 if(!lun_set)
4205 {
4206 lun = partition_get_lun(index);
4207 mmc_set_lun(lun);
4208 }
4209
4210 size = partition_get_size(index);
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05304211 if (ROUND_TO_PAGE(sz, mmc_blocksize_mask) > size) {
Mao Jinlong226f33a2014-07-04 17:24:10 +08004212 fastboot_fail("size too large");
4213 return;
4214 }
4215 else if (mmc_write(ptn , sz, (unsigned int *)data)) {
4216 fastboot_fail("flash write failure");
4217 return;
4218 }
Greg Grisco6e754772011-06-23 12:19:39 -07004219 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07004220 }
4221 fastboot_okay("");
4222 return;
4223}
4224
Ajay Dudanide984792015-03-02 09:57:41 -08004225void cmd_flash_meta_img(const char *arg, void *data, unsigned sz)
4226{
4227 int i, images;
4228 meta_header_t *meta_header;
4229 img_header_entry_t *img_header_entry;
Parth Dixit3e2d3032016-03-04 17:11:52 +05304230 /*End of the image address*/
4231 uintptr_t data_end;
4232
4233 if( (UINT_MAX - sz) > (uintptr_t)data )
4234 data_end = (uintptr_t)data + sz;
4235 else
4236 {
4237 fastboot_fail("Cannot flash: image header corrupt");
4238 return;
4239 }
4240
Ashish Bhimanpalliwar21494e12020-10-07 13:24:03 +05304241 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 +05304242 {
4243 fastboot_fail("Cannot flash: image header corrupt");
4244 return;
4245 }
Ajay Dudanide984792015-03-02 09:57:41 -08004246
lijuang8ee21882016-04-19 16:57:11 +08004247 /* If device is locked:
4248 * Forbid to flash image to avoid the device to bypass the image
4249 * which with "any" name other than bootloader. Because it maybe
4250 * a meta package of all partitions.
4251 */
Monika Singh292b3e92018-03-17 22:40:23 +05304252#if VERIFIED_BOOT || VERIFIED_BOOT_2
lijuang8ee21882016-04-19 16:57:11 +08004253 if (target_build_variant_user()) {
4254 if (!device.is_unlocked) {
4255 fastboot_fail("Device is locked, meta image flashing is not allowed");
4256 return;
4257 }
Mayank Grover889be1b2017-09-12 20:12:23 +05304258
Mayank Grover912eaa62017-10-26 12:08:53 +05304259 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304260 !device.is_unlock_critical)
4261 {
lijuang8ee21882016-04-19 16:57:11 +08004262 fastboot_fail("Device is critical locked, Meta image flashing is not allowed");
4263 return;
4264 }
lijuang8ee21882016-04-19 16:57:11 +08004265 }
4266#endif
4267
Ajay Dudanide984792015-03-02 09:57:41 -08004268 meta_header = (meta_header_t*) data;
Ashish Bhimanpalliwar21494e12020-10-07 13:24:03 +05304269 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 +05304270 {
4271 fastboot_fail("Cannot flash: image header corrupt");
4272 return;
4273 }
Ajay Dudanide984792015-03-02 09:57:41 -08004274 img_header_entry = (img_header_entry_t*) (data+sizeof(meta_header_t));
4275
4276 images = meta_header->img_hdr_sz / sizeof(img_header_entry_t);
4277
4278 for (i=0; i<images; i++) {
4279
4280 if((img_header_entry[i].ptn_name == NULL) ||
4281 (img_header_entry[i].start_offset == 0) ||
4282 (img_header_entry[i].size == 0))
4283 break;
Kishor PK49831502017-04-21 17:55:43 +05304284 if ((UINT_MAX - img_header_entry[i].start_offset) < (uintptr_t)data) {
4285 fastboot_fail("Integer overflow detected in start_offset of img");
4286 break;
4287 }
4288 else if ((UINT_MAX - (img_header_entry[i].start_offset + (uintptr_t)data)) < img_header_entry[i].size) {
4289 fastboot_fail("Integer overflow detected in size of img");
4290 break;
4291 }
Parth Dixit3e2d3032016-03-04 17:11:52 +05304292 if( data_end < ((uintptr_t)data + img_header_entry[i].start_offset
4293 + img_header_entry[i].size) )
4294 {
4295 fastboot_fail("Cannot flash: image size mismatch");
4296 break;
4297 }
4298
Ajay Dudanide984792015-03-02 09:57:41 -08004299 cmd_flash_mmc_img(img_header_entry[i].ptn_name,
4300 (void *) data + img_header_entry[i].start_offset,
4301 img_header_entry[i].size);
4302 }
4303
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08004304 if (!strncmp(arg, "bootloader", strlen("bootloader")))
4305 {
4306 strlcpy(device.bootloader_version, TARGET(BOARD), MAX_VERSION_LEN);
4307 strlcat(device.bootloader_version, "-", MAX_VERSION_LEN);
4308 strlcat(device.bootloader_version, meta_header->img_version, MAX_VERSION_LEN);
4309 }
4310 else
4311 {
4312 strlcpy(device.radio_version, TARGET(BOARD), MAX_VERSION_LEN);
4313 strlcat(device.radio_version, "-", MAX_VERSION_LEN);
4314 strlcat(device.radio_version, meta_header->img_version, MAX_VERSION_LEN);
4315 }
4316
4317 write_device_info(&device);
Ajay Dudanide984792015-03-02 09:57:41 -08004318 fastboot_okay("");
4319 return;
4320}
4321
Ajay Dudani5c761132011-04-07 20:19:04 -07004322void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
4323{
4324 unsigned int chunk;
wufeng.jiang813dc352015-06-02 23:02:46 -04004325 uint64_t chunk_data_sz;
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004326 uint32_t *fill_buf = NULL;
4327 uint32_t fill_val;
Mayank Grover4f50bba2017-07-19 18:17:08 +05304328 uint32_t blk_sz_actual = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07004329 sparse_header_t *sparse_header;
4330 chunk_header_t *chunk_header;
Ajay Dudaniab18f022011-05-12 14:39:22 -07004331 uint32_t total_blocks = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07004332 unsigned long long ptn = 0;
Channagoud Kadabi65b91002011-10-11 17:34:33 +05304333 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07004334 int index = INVALID_PTN;
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05304335 uint32_t i;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004336 uint8_t lun = 0;
vijay kumar800255e2015-04-24 20:26:19 +05304337 /*End of the sparse image address*/
Parth Dixit64b1a482016-03-07 16:31:26 +05304338 uintptr_t data_end = (uintptr_t)data + sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07004339
Kinson Chikf1a43512011-07-14 11:28:39 -07004340 index = partition_get_index(arg);
4341 ptn = partition_get_offset(index);
4342 if(ptn == 0) {
Ajay Dudani5c761132011-04-07 20:19:04 -07004343 fastboot_fail("partition table doesn't exist");
4344 return;
4345 }
4346
Channagoud Kadabi65b91002011-10-11 17:34:33 +05304347 size = partition_get_size(index);
Channagoud Kadabi65b91002011-10-11 17:34:33 +05304348
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08004349 lun = partition_get_lun(index);
4350 mmc_set_lun(lun);
4351
vijay kumar800255e2015-04-24 20:26:19 +05304352 if (sz < sizeof(sparse_header_t)) {
4353 fastboot_fail("size too low");
4354 return;
4355 }
4356
Ajay Dudani5c761132011-04-07 20:19:04 -07004357 /* Read and skip over sparse image header */
4358 sparse_header = (sparse_header_t *) data;
vijay kumar800255e2015-04-24 20:26:19 +05304359
Mayank Grover48bd9bb2017-07-19 12:04:16 +05304360 if (!sparse_header->blk_sz || (sparse_header->blk_sz % 4)){
4361 fastboot_fail("Invalid block size\n");
4362 return;
4363 }
4364
vijay kumar1321f342015-03-27 12:13:42 +05304365 if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
Ajay Dudani876b3282012-12-21 14:12:17 -08004366 fastboot_fail("size too large");
4367 return;
4368 }
4369
vijay kumarde4fcf62015-04-23 13:05:49 +05304370 data += sizeof(sparse_header_t);
vijay kumar800255e2015-04-24 20:26:19 +05304371
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
vijay kumarde4fcf62015-04-23 13:05:49 +05304377 if(sparse_header->file_hdr_sz != sizeof(sparse_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07004378 {
vijay kumarde4fcf62015-04-23 13:05:49 +05304379 fastboot_fail("sparse header size mismatch");
4380 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07004381 }
4382
Ajay Dudanib06c05f2011-05-12 14:46:10 -07004383 dprintf (SPEW, "=== Sparse Image Header ===\n");
4384 dprintf (SPEW, "magic: 0x%x\n", sparse_header->magic);
4385 dprintf (SPEW, "major_version: 0x%x\n", sparse_header->major_version);
4386 dprintf (SPEW, "minor_version: 0x%x\n", sparse_header->minor_version);
4387 dprintf (SPEW, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
4388 dprintf (SPEW, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
4389 dprintf (SPEW, "blk_sz: %d\n", sparse_header->blk_sz);
4390 dprintf (SPEW, "total_blks: %d\n", sparse_header->total_blks);
4391 dprintf (SPEW, "total_chunks: %d\n", sparse_header->total_chunks);
Ajay Dudani5c761132011-04-07 20:19:04 -07004392
4393 /* Start processing chunks */
4394 for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
4395 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304396 /* Make sure the total image size does not exceed the partition size */
4397 if(((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz) >= size) {
4398 fastboot_fail("size too large");
4399 return;
4400 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004401 /* Read and skip over chunk header */
4402 chunk_header = (chunk_header_t *) data;
4403 data += sizeof(chunk_header_t);
4404
Parth Dixit64b1a482016-03-07 16:31:26 +05304405 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304406 fastboot_fail("buffer overreads occured due to invalid sparse header");
4407 return;
4408 }
4409
Ajay Dudani5c761132011-04-07 20:19:04 -07004410 dprintf (SPEW, "=== Chunk Header ===\n");
4411 dprintf (SPEW, "chunk_type: 0x%x\n", chunk_header->chunk_type);
4412 dprintf (SPEW, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
4413 dprintf (SPEW, "total_size: 0x%x\n", chunk_header->total_sz);
4414
vijay kumar800255e2015-04-24 20:26:19 +05304415 if(sparse_header->chunk_hdr_sz != sizeof(chunk_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07004416 {
vijay kumar800255e2015-04-24 20:26:19 +05304417 fastboot_fail("chunk header size mismatch");
4418 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07004419 }
4420
wufeng.jiang813dc352015-06-02 23:02:46 -04004421 chunk_data_sz = (uint64_t)sparse_header->blk_sz * chunk_header->chunk_sz;
4422
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304423 /* Make sure that the chunk size calculated from sparse image does not
4424 * exceed partition size
4425 */
4426 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + chunk_data_sz > size)
4427 {
4428 fastboot_fail("Chunk data size exceeds partition size");
4429 return;
4430 }
4431
Ajay Dudani5c761132011-04-07 20:19:04 -07004432 switch (chunk_header->chunk_type)
4433 {
4434 case CHUNK_TYPE_RAW:
wufeng.jiang813dc352015-06-02 23:02:46 -04004435 if((uint64_t)chunk_header->total_sz != ((uint64_t)sparse_header->chunk_hdr_sz +
Ajay Dudani5c761132011-04-07 20:19:04 -07004436 chunk_data_sz))
4437 {
4438 fastboot_fail("Bogus chunk size for chunk type Raw");
4439 return;
4440 }
4441
Parth Dixit64b1a482016-03-07 16:31:26 +05304442 if (data_end < (uintptr_t)data + chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05304443 fastboot_fail("buffer overreads occured due to invalid sparse header");
4444 return;
4445 }
4446
wufeng.jiang813dc352015-06-02 23:02:46 -04004447 /* chunk_header->total_sz is uint32,So chunk_data_sz is now less than 2^32
4448 otherwise it will return in the line above
4449 */
Ajay Dudaniab18f022011-05-12 14:39:22 -07004450 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
wufeng.jiang813dc352015-06-02 23:02:46 -04004451 (uint32_t)chunk_data_sz,
Ajay Dudaniab18f022011-05-12 14:39:22 -07004452 (unsigned int*)data))
Ajay Dudani5c761132011-04-07 20:19:04 -07004453 {
4454 fastboot_fail("flash write failure");
4455 return;
4456 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304457 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4458 fastboot_fail("Bogus size for RAW chunk type");
4459 return;
4460 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004461 total_blocks += chunk_header->chunk_sz;
wufeng.jiang813dc352015-06-02 23:02:46 -04004462 data += (uint32_t)chunk_data_sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07004463 break;
4464
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004465 case CHUNK_TYPE_FILL:
4466 if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
4467 sizeof(uint32_t)))
4468 {
4469 fastboot_fail("Bogus chunk size for chunk type FILL");
4470 return;
4471 }
4472
Mayank Grover4f50bba2017-07-19 18:17:08 +05304473 blk_sz_actual = ROUNDUP(sparse_header->blk_sz, CACHE_LINE);
4474 /* Integer overflow detected */
4475 if (blk_sz_actual < sparse_header->blk_sz)
4476 {
4477 fastboot_fail("Invalid block size");
4478 return;
4479 }
4480
4481 fill_buf = (uint32_t *)memalign(CACHE_LINE, blk_sz_actual);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004482 if (!fill_buf)
4483 {
4484 fastboot_fail("Malloc failed for: CHUNK_TYPE_FILL");
4485 return;
4486 }
4487
Parth Dixit64b1a482016-03-07 16:31:26 +05304488 if (data_end < (uintptr_t)data + sizeof(uint32_t)) {
vijay kumar800255e2015-04-24 20:26:19 +05304489 fastboot_fail("buffer overreads occured due to invalid sparse header");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304490 free(fill_buf);
vijay kumar800255e2015-04-24 20:26:19 +05304491 return;
4492 }
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004493 fill_val = *(uint32_t *)data;
4494 data = (char *) data + sizeof(uint32_t);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004495
4496 for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++)
4497 {
4498 fill_buf[i] = fill_val;
4499 }
4500
Gaurav Nebhwanie94cbe12016-03-17 21:16:34 +05304501 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz))
4502 {
4503 fastboot_fail("bogus size for chunk FILL type");
4504 free(fill_buf);
4505 return;
4506 }
4507
wufeng.jiang813dc352015-06-02 23:02:46 -04004508 for (i = 0; i < chunk_header->chunk_sz; i++)
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004509 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304510 /* Make sure that the data written to partition does not exceed partition size */
4511 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + sparse_header->blk_sz > size)
4512 {
4513 fastboot_fail("Chunk data size for fill type exceeds partition size");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304514 free(fill_buf);
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304515 return;
4516 }
4517
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004518 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
4519 sparse_header->blk_sz,
4520 fill_buf))
4521 {
4522 fastboot_fail("flash write failure");
4523 free(fill_buf);
4524 return;
4525 }
4526
4527 total_blocks++;
4528 }
4529
4530 free(fill_buf);
4531 break;
4532
Ajay Dudani5c761132011-04-07 20:19:04 -07004533 case CHUNK_TYPE_DONT_CARE:
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304534 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4535 fastboot_fail("bogus size for chunk DONT CARE type");
4536 return;
4537 }
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004538 total_blocks += chunk_header->chunk_sz;
4539 break;
4540
Ajay Dudani5c761132011-04-07 20:19:04 -07004541 case CHUNK_TYPE_CRC:
4542 if(chunk_header->total_sz != sparse_header->chunk_hdr_sz)
4543 {
wufeng.jiang813dc352015-06-02 23:02:46 -04004544 fastboot_fail("Bogus chunk size for chunk type CRC");
Ajay Dudani5c761132011-04-07 20:19:04 -07004545 return;
4546 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304547 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4548 fastboot_fail("bogus size for chunk CRC type");
4549 return;
4550 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004551 total_blocks += chunk_header->chunk_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304552 if ((uintptr_t)data > UINT_MAX - chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05304553 fastboot_fail("integer overflow occured");
4554 return;
4555 }
wufeng.jiang813dc352015-06-02 23:02:46 -04004556 data += (uint32_t)chunk_data_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304557 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304558 fastboot_fail("buffer overreads occured due to invalid sparse header");
4559 return;
4560 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004561 break;
4562
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004563 default:
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004564 dprintf(CRITICAL, "Unkown chunk type: %x\n",chunk_header->chunk_type);
Ajay Dudani5c761132011-04-07 20:19:04 -07004565 fastboot_fail("Unknown chunk type");
4566 return;
4567 }
4568 }
4569
Ajay Dudani0c6927b2011-05-18 11:12:16 -07004570 dprintf(INFO, "Wrote %d blocks, expected to write %d blocks\n",
4571 total_blocks, sparse_header->total_blks);
4572
4573 if(total_blocks != sparse_header->total_blks)
4574 {
4575 fastboot_fail("sparse image write failure");
4576 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004577
4578 fastboot_okay("");
4579 return;
4580}
4581
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304582static bool CheckVirtualAbCriticalPartition (const char *PartitionName)
4583{
4584 VirtualAbMergeStatus SnapshotMergeStatus;
4585 uint32 Iter = 0;
4586
4587 SnapshotMergeStatus = GetSnapshotMergeStatus ();
4588 if ((SnapshotMergeStatus == MERGING || SnapshotMergeStatus == SNAPSHOTTED)) {
4589 for (Iter = 0; Iter < ARRAY_SIZE (VirtualAbCriticalPartitions); Iter++) {
4590 if (!strncmp (PartitionName, VirtualAbCriticalPartitions[Iter],
4591 strlen (VirtualAbCriticalPartitions[Iter])))
4592 return true;
4593 }
4594 }
4595 return false;
4596}
4597
Ajay Dudani5c761132011-04-07 20:19:04 -07004598void cmd_flash_mmc(const char *arg, void *data, unsigned sz)
4599{
4600 sparse_header_t *sparse_header;
Ajay Dudanide984792015-03-02 09:57:41 -08004601 meta_header_t *meta_header;
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304602 VirtualAbMergeStatus SnapshotMergeStatus;
4603 char FlashResultStr[MAX_RSP_SIZE] = "";
Ajay Dudani5c761132011-04-07 20:19:04 -07004604
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004605#ifdef SSD_ENABLE
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08004606 /* 8 Byte Magic + 2048 Byte xml + Encrypted Data */
4607 unsigned int *magic_number = (unsigned int *) data;
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004608 int ret=0;
4609 uint32 major_version=0;
4610 uint32 minor_version=0;
4611
4612 ret = scm_svc_version(&major_version,&minor_version);
4613 if(!ret)
4614 {
4615 if(major_version >= 2)
4616 {
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004617 if( !strcmp(arg, "ssd") || !strcmp(arg, "tqs") )
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004618 {
4619 ret = encrypt_scm((uint32 **) &data, &sz);
4620 if (ret != 0) {
4621 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4622 return;
4623 }
4624
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004625 /* Protect only for SSD */
4626 if (!strcmp(arg, "ssd")) {
4627 ret = scm_protect_keystore((uint32 *) data, sz);
4628 if (ret != 0) {
4629 dprintf(CRITICAL, "ERROR: scm_protect_keystore Failed\n");
4630 return;
4631 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004632 }
4633 }
4634 else
4635 {
4636 ret = decrypt_scm_v2((uint32 **) &data, &sz);
4637 if(ret != 0)
4638 {
4639 dprintf(CRITICAL,"ERROR: Decryption Failure\n");
4640 return;
4641 }
4642 }
4643 }
4644 else
4645 {
4646 if (magic_number[0] == DECRYPT_MAGIC_0 &&
4647 magic_number[1] == DECRYPT_MAGIC_1)
4648 {
4649 ret = decrypt_scm((uint32 **) &data, &sz);
4650 if (ret != 0) {
4651 dprintf(CRITICAL, "ERROR: Invalid secure image\n");
4652 return;
4653 }
4654 }
4655 else if (magic_number[0] == ENCRYPT_MAGIC_0 &&
4656 magic_number[1] == ENCRYPT_MAGIC_1)
4657 {
4658 ret = encrypt_scm((uint32 **) &data, &sz);
4659 if (ret != 0) {
4660 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4661 return;
4662 }
4663 }
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004664 }
4665 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004666 else
Neeti Desai127b9e02012-03-20 16:11:23 -07004667 {
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004668 dprintf(CRITICAL,"INVALID SVC Version\n");
4669 return;
Neeti Desai127b9e02012-03-20 16:11:23 -07004670 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004671#endif /* SSD_ENABLE */
Neeti Desai127b9e02012-03-20 16:11:23 -07004672
Monika Singh292b3e92018-03-17 22:40:23 +05304673#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07004674 if (target_build_variant_user())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004675 {
lijuang511a2b52015-08-14 20:50:51 +08004676 /* if device is locked:
4677 * common partition will not allow to be flashed
4678 * critical partition will allow to flash image.
4679 */
4680 if(!device.is_unlocked && !critical_flash_allowed(arg)) {
4681 fastboot_fail("Partition flashing is not allowed");
4682 return;
4683 }
Mayank Grover889be1b2017-09-12 20:12:23 +05304684
lijuang511a2b52015-08-14 20:50:51 +08004685 /* if device critical is locked:
4686 * common partition will allow to be flashed
4687 * critical partition will not allow to flash image.
4688 */
Mayank Grover912eaa62017-10-26 12:08:53 +05304689 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304690 !device.is_unlock_critical &&
4691 critical_flash_allowed(arg)) {
4692 fastboot_fail("Critical partition flashing is not allowed");
4693 return;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004694 }
4695 }
4696#endif
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304697
4698 if (target_virtual_ab_supported())
4699 {
4700 if (CheckVirtualAbCriticalPartition (arg)) {
4701 snprintf(FlashResultStr, MAX_RSP_SIZE,"Flashing of %s is not allowed in %s state",
4702 arg, SnapshotMergeState);
4703 fastboot_fail(FlashResultStr);
4704 return;
4705 }
4706
4707 SnapshotMergeStatus = GetSnapshotMergeStatus ();
4708 if (((SnapshotMergeStatus == MERGING) || (SnapshotMergeStatus == SNAPSHOTTED)) &&
4709 !strncmp (arg, "super", strlen ("super"))) {
4710 if(SetSnapshotMergeStatus (CANCELLED))
4711 {
4712 fastboot_fail("Failed to update snapshot state to cancel");
4713 return;
4714 }
4715
4716 //updating fbvar snapshot-merge-state
4717 snprintf(SnapshotMergeState,strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
4718 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
4719 }
4720 }
4721
Monika Singh292b3e92018-03-17 22:40:23 +05304722 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4723 dprintf(INFO, "flashing avb_custom_key\n");
4724 if (store_userkey(data, sz)) {
4725 fastboot_fail("Flashing avb_custom_key failed");
4726 } else {
4727 fastboot_okay("");
4728 }
4729 return;
4730 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004731
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004732 sparse_header = (sparse_header_t *) data;
Ajay Dudanide984792015-03-02 09:57:41 -08004733 meta_header = (meta_header_t *) data;
4734 if (sparse_header->magic == SPARSE_HEADER_MAGIC)
Ajay Dudani5c761132011-04-07 20:19:04 -07004735 cmd_flash_mmc_sparse_img(arg, data, sz);
Ajay Dudanide984792015-03-02 09:57:41 -08004736 else if (meta_header->magic == META_HEADER_MAGIC)
4737 cmd_flash_meta_img(arg, data, sz);
4738 else
4739 cmd_flash_mmc_img(arg, data, sz);
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004740
4741#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +05304742 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304743 (!strncmp(arg, "system", 6)) &&
4744 !device.verity_mode)
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004745 // reset dm_verity mode to enforcing
4746 device.verity_mode = 1;
4747 write_device_info(&device);
Parth Dixitddbc7352015-10-18 03:13:31 +05304748#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004749
Ajay Dudani5c761132011-04-07 20:19:04 -07004750 return;
4751}
4752
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004753void cmd_updatevol(const char *vol_name, void *data, unsigned sz)
4754{
4755 struct ptentry *sys_ptn;
4756 struct ptable *ptable;
4757
4758 ptable = flash_get_ptable();
4759 if (ptable == NULL) {
4760 fastboot_fail("partition table doesn't exist");
4761 return;
4762 }
4763
4764 sys_ptn = ptable_find(ptable, "system");
4765 if (sys_ptn == NULL) {
4766 fastboot_fail("system partition not found");
4767 return;
4768 }
4769
4770 sz = ROUND_TO_PAGE(sz, page_mask);
4771 if (update_ubi_vol(sys_ptn, vol_name, data, sz))
4772 fastboot_fail("update_ubi_vol failed");
4773 else
4774 fastboot_okay("");
4775}
4776
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004777void cmd_flash_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08004778{
4779 struct ptentry *ptn;
4780 struct ptable *ptable;
4781 unsigned extra = 0;
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304782 uint64_t partition_size = 0;
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304783 unsigned bytes_to_round_page = 0;
4784 unsigned rounded_size = 0;
Dima Zavin214cc642009-01-26 11:16:21 -08004785
Kishor PK38ed93d2017-04-25 14:19:26 +05304786 if((uintptr_t)data > (UINT_MAX - sz)) {
4787 fastboot_fail("Cannot flash: image header corrupt");
4788 return;
4789 }
4790
Dima Zavin214cc642009-01-26 11:16:21 -08004791 ptable = flash_get_ptable();
4792 if (ptable == NULL) {
4793 fastboot_fail("partition table doesn't exist");
4794 return;
4795 }
4796
4797 ptn = ptable_find(ptable, arg);
4798 if (ptn == NULL) {
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004799 dprintf(INFO, "unknown partition name (%s). Trying updatevol\n",
4800 arg);
4801 cmd_updatevol(arg, data, sz);
Dima Zavin214cc642009-01-26 11:16:21 -08004802 return;
4803 }
4804
Monika Singh292b3e92018-03-17 22:40:23 +05304805 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4806 dprintf(INFO, "flashing avb_custom_key\n");
4807 if (store_userkey(data, sz)) {
4808 fastboot_fail("Flashing avb_custom_key failed");
4809 } else {
4810 fastboot_okay("");
4811 }
4812 return;
4813 }
4814
Dima Zavin214cc642009-01-26 11:16:21 -08004815 if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) {
Kishor PK38ed93d2017-04-25 14:19:26 +05304816 if((sz > BOOT_MAGIC_SIZE) && (!memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE))) {
4817 dprintf(INFO, "Verified the BOOT_MAGIC in image header \n");
4818 } else {
4819 fastboot_fail("Image is not a boot image");
Dima Zavin214cc642009-01-26 11:16:21 -08004820 return;
4821 }
4822 }
4823
Amol Jadi5c61a952012-05-04 17:05:35 -07004824 if (!strcmp(ptn->name, "system")
Deepa Dinamani13e32c42012-03-12 14:34:17 -07004825 || !strcmp(ptn->name, "userdata")
4826 || !strcmp(ptn->name, "persist")
Sundarajan Srinivasanb063a852013-11-19 14:02:27 -08004827 || !strcmp(ptn->name, "recoveryfs")
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -08004828 || !strcmp(ptn->name, "modem"))
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004829 extra = 1;
Kishor PK38ed93d2017-04-25 14:19:26 +05304830 else {
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304831 rounded_size = ROUNDUP(sz, page_size);
4832 bytes_to_round_page = rounded_size - sz;
4833 if (bytes_to_round_page) {
4834 if (((uintptr_t)data + sz ) > (UINT_MAX - bytes_to_round_page)) {
4835 fastboot_fail("Integer overflow detected");
4836 return;
4837 }
4838 if (((uintptr_t)data + sz + bytes_to_round_page) >
4839 ((uintptr_t)target_get_scratch_address() + target_get_max_flash_size())) {
4840 fastboot_fail("Buffer size is not aligned to page_size");
4841 return;
4842 }
4843 else {
4844 memset(data + sz, 0, bytes_to_round_page);
4845 sz = rounded_size;
4846 }
Kishor PK38ed93d2017-04-25 14:19:26 +05304847 }
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304848 }
4849
Kishor PK38ed93d2017-04-25 14:19:26 +05304850 /*Checking partition_size for the possible integer overflow */
4851 partition_size = validate_partition_size(ptn);
4852
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304853 if (sz > partition_size) {
4854 fastboot_fail("Image size too large");
4855 return;
4856 }
4857
Dima Zavin214cc642009-01-26 11:16:21 -08004858 dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name);
Mayank Grover6cde9352017-06-06 18:45:23 +05304859 if ((sz > UBI_EC_HDR_SIZE) &&
4860 (!memcmp((void *)data, UBI_MAGIC, UBI_MAGIC_SIZE))) {
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004861 if (flash_ubi_img(ptn, data, sz)) {
4862 fastboot_fail("flash write failure");
4863 return;
4864 }
4865 } else {
4866 if (flash_write(ptn, extra, data, sz)) {
4867 fastboot_fail("flash write failure");
4868 return;
4869 }
Dima Zavin214cc642009-01-26 11:16:21 -08004870 }
4871 dprintf(INFO, "partition '%s' updated\n", ptn->name);
4872 fastboot_okay("");
4873}
4874
Kishor PK38ed93d2017-04-25 14:19:26 +05304875
4876static inline uint64_t validate_partition_size(struct ptentry *ptn)
4877{
4878 if (ptn->length && flash_num_pages_per_blk() && page_size) {
4879 if ((ptn->length < ( UINT_MAX / flash_num_pages_per_blk())) && ((ptn->length * flash_num_pages_per_blk()) < ( UINT_MAX / page_size))) {
4880 return ptn->length * flash_num_pages_per_blk() * page_size;
4881 }
4882 }
4883 return 0;
4884}
4885
4886
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004887void cmd_flash(const char *arg, void *data, unsigned sz)
4888{
4889 if(target_is_emmc_boot())
4890 cmd_flash_mmc(arg, data, sz);
4891 else
4892 cmd_flash_nand(arg, data, sz);
4893}
4894
Dima Zavin214cc642009-01-26 11:16:21 -08004895void cmd_continue(const char *arg, void *data, unsigned sz)
4896{
4897 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07004898 fastboot_stop();
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004899
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004900 if (target_is_emmc_boot())
4901 {
lijuanga40d6302015-07-20 20:10:13 +08004902#if FBCON_DISPLAY_MSG
lijuangde34d502016-02-26 16:04:50 +08004903 /* Exit keys' detection thread firstly */
4904 exit_menu_keys_detection();
lijuanga40d6302015-07-20 20:10:13 +08004905#endif
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004906 boot_linux_from_mmc();
4907 }
4908 else
4909 {
4910 boot_linux_from_flash();
4911 }
Dima Zavin214cc642009-01-26 11:16:21 -08004912}
4913
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004914void cmd_reboot(const char *arg, void *data, unsigned sz)
4915{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004916 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004917 fastboot_okay("");
4918 reboot_device(0);
4919}
4920
Mayank Grover351a75e2017-05-30 20:06:08 +05304921void cmd_set_active(const char *arg, void *data, unsigned sz)
4922{
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304923 char *p, *sp = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05304924 unsigned i,current_active_slot;
4925 const char *current_slot_suffix;
4926
4927 if (!partition_multislot_is_supported())
4928 {
4929 fastboot_fail("Command not supported");
4930 return;
4931 }
4932
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304933 if (target_virtual_ab_supported()) {
4934 if (GetSnapshotMergeStatus () == MERGING) {
4935 fastboot_fail ("Slot Change is not allowed in merging state");
4936 return;
4937 }
4938 }
4939
Mayank Grover351a75e2017-05-30 20:06:08 +05304940 if (arg)
4941 {
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304942 p = strtok_r((char *)arg, ":", &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304943 if (p)
Mayank Grover351a75e2017-05-30 20:06:08 +05304944 {
4945 current_active_slot = partition_find_active_slot();
4946
4947 /* Check if trying to make curent slot active */
4948 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304949 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4950 (char *)suffix_delimiter, &sp);
4951
Mayank Grover5eb5f692017-07-19 20:16:04 +05304952 if (current_slot_suffix &&
4953 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304954 {
4955 fastboot_okay("Slot already set active");
4956 return;
4957 }
4958 else
4959 {
4960 for (i = 0; i < AB_SUPPORTED_SLOTS; i++)
4961 {
4962 current_slot_suffix = SUFFIX_SLOT(i);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304963 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4964 (char *)suffix_delimiter, &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304965 if (current_slot_suffix &&
4966 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304967 {
lijuang8b03e5f2019-07-12 18:16:19 +08004968 partition_switch_slots(current_active_slot, i, true);
Mayank Grover351a75e2017-05-30 20:06:08 +05304969 publish_getvar_multislot_vars();
4970 fastboot_okay("");
4971 return;
4972 }
4973 }
4974 }
4975 }
4976 }
4977 fastboot_fail("Invalid slot suffix.");
4978 return;
4979}
4980
Mayank Grover98c4c742019-04-25 17:21:37 +05304981void cmd_reboot_fastboot(const char *arg, void *data, unsigned sz)
4982{
4983 dprintf(INFO, "rebooting the device - userspace fastboot\n");
4984 if (send_recovery_cmd(RECOVERY_BOOT_FASTBOOT_CMD)) {
4985 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4986 fastboot_fail("Failed to update recovery command");
4987 return;
4988 }
4989 fastboot_okay("");
4990 reboot_device(REBOOT_MODE_UNKNOWN);
4991
4992 //shouldn't come here.
4993 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4994 return;
4995}
4996
4997void cmd_reboot_recovery(const char *arg, void *data, unsigned sz)
4998{
4999 dprintf(INFO, "rebooting the device - recovery\n");
5000 if (send_recovery_cmd(RECOVERY_BOOT_RECOVERY_CMD)) {
5001 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
5002 fastboot_fail("Failed to update recovery command");
5003 return;
5004 }
5005 fastboot_okay("");
5006 reboot_device(REBOOT_MODE_UNKNOWN);
5007
5008 //shouldn't come here.
5009 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
5010 return;
5011}
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05305012
Luca Weiss7f063f12022-04-14 11:06:43 +02005013#if DYNAMIC_PARTITION_SUPPORT
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05305014#ifdef VIRTUAL_AB_OTA
5015void CmdUpdateSnapshot(const char *arg, void *data, unsigned sz)
5016{
5017 char *command = NULL;
5018 const char *delim = ":";
5019 char *sp;
5020
5021 if (arg) {
5022 command = strtok_r((char *)arg, delim, &sp);
5023 if (command) {
5024 command++;
5025
5026 if(!strncmp (command, "merge", AsciiStrLen ("merge"))) {
5027 if (GetSnapshotMergeStatus () == MERGING) {
5028 cmd_reboot_fastboot(Arg, Data, Size);
5029 }
5030 FastbootOkay ("");
5031 return;
5032 }
5033 else if (!strncmp (Command, "cancel", AsciiStrLen ("cancel"))) {
5034 if(!device.is_unlocked) {
5035 fastboot_fail ("Snapshot Cancel is not allowed in Lock State");
5036 return;
5037 }
5038
5039 if (SetSnapshotMergeStatus (CANCELLED))
5040 {
5041 fastboot_fail("Failed to update snapshot state to cancel");
5042 return;
5043 }
5044
5045 //updating fbvar snapshot-merge-state
5046 snprintf(SnapshotMergeState, strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
5047 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
5048 fastboot_okay("");
5049 return;
5050 }
5051 }
5052 }
5053 fastboot_fail("Invalid snapshot-update command");
5054 return;
5055}
5056#endif
Mayank Grover98c4c742019-04-25 17:21:37 +05305057#endif
5058
Chandan Uddaraju94183c02010-01-15 15:13:59 -08005059void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz)
5060{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005061 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08005062 fastboot_okay("");
5063 reboot_device(FASTBOOT_MODE);
5064}
5065
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005066void cmd_oem_enable_charger_screen(const char *arg, void *data, unsigned size)
5067{
5068 dprintf(INFO, "Enabling charger screen check\n");
5069 device.charger_screen_enabled = 1;
5070 write_device_info(&device);
5071 fastboot_okay("");
5072}
5073
5074void cmd_oem_disable_charger_screen(const char *arg, void *data, unsigned size)
5075{
5076 dprintf(INFO, "Disabling charger screen check\n");
5077 device.charger_screen_enabled = 0;
5078 write_device_info(&device);
5079 fastboot_okay("");
5080}
5081
tracychui9d60fc52020-06-05 17:31:38 +08005082#if defined(ENABLE_PRODINFO_ACCESS)
5083void CmdOemEnableAdb(const char *arg, void *data, unsigned size)
5084{
5085 dprintf(INFO, "Enabling Adb\n");
5086 prod.is_adb_enabled = 1;
5087 write_prod_info(&prod);
5088 fastboot_okay("");
5089}
5090#endif
5091
lijuanga25d8bb2015-09-16 13:11:52 +08005092void cmd_oem_off_mode_charger(const char *arg, void *data, unsigned size)
5093{
5094 char *p = NULL;
5095 const char *delim = " \t\n\r";
Parth Dixit407f15b2016-01-07 14:47:37 +05305096 char *sp;
lijuanga25d8bb2015-09-16 13:11:52 +08005097
5098 if (arg) {
Parth Dixit407f15b2016-01-07 14:47:37 +05305099 p = strtok_r((char *)arg, delim, &sp);
lijuanga25d8bb2015-09-16 13:11:52 +08005100 if (p) {
5101 if (!strncmp(p, "0", 1)) {
5102 device.charger_screen_enabled = 0;
5103 } else if (!strncmp(p, "1", 1)) {
5104 device.charger_screen_enabled = 1;
5105 }
5106 }
5107 }
5108
5109 /* update charger_screen_enabled value for getvar
5110 * command
5111 */
5112 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
5113 device.charger_screen_enabled);
5114
5115 write_device_info(&device);
5116 fastboot_okay("");
5117}
5118
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305119void cmd_oem_select_display_panel(const char *arg, void *data, unsigned size)
5120{
5121 dprintf(INFO, "Selecting display panel %s\n", arg);
5122 if (arg)
5123 strlcpy(device.display_panel, arg,
5124 sizeof(device.display_panel));
5125 write_device_info(&device);
5126 fastboot_okay("");
5127}
5128
Shashank Mittal162244e2011-08-08 19:01:25 -07005129void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
5130{
lijuang4ece1e72015-08-14 21:02:36 +08005131 set_device_unlock(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05305132}
5133
5134void cmd_oem_unlock_go(const char *arg, void *data, unsigned sz)
5135{
lijuang4ece1e72015-08-14 21:02:36 +08005136 if(!device.is_unlocked) {
vijay kumarc65876c2015-04-24 13:29:16 +05305137 if(!is_allow_unlock) {
5138 fastboot_fail("oem unlock is not allowed");
5139 return;
5140 }
5141
lijuang4ece1e72015-08-14 21:02:36 +08005142 set_device_unlock_value(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05305143
lijuang4ece1e72015-08-14 21:02:36 +08005144 /* wipe data */
vijay kumarc65876c2015-04-24 13:29:16 +05305145 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05305146 memset(&msg, 0, sizeof(msg));
vijay kumarc65876c2015-04-24 13:29:16 +05305147 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
5148 write_misc(0, &msg, sizeof(msg));
5149
5150 fastboot_okay("");
5151 reboot_device(RECOVERY_MODE);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07005152 }
5153 fastboot_okay("");
5154}
5155
Channagoud Kadabiad259832015-05-29 11:14:17 -07005156static int aboot_frp_unlock(char *pname, void *data, unsigned sz)
5157{
Mayank Grover70f8b0e2017-05-17 11:49:00 +05305158 int ret=1;
5159 bool authentication_success=false;
Channagoud Kadabiad259832015-05-29 11:14:17 -07005160
Mayank Grover70f8b0e2017-05-17 11:49:00 +05305161 /*
5162 Authentication method not implemented.
5163
5164 OEM to implement, authentication system which on successful validataion,
5165 calls write_allow_oem_unlock() with is_allow_unlock.
5166 */
5167#if 0
5168 authentication_success = oem_specific_auth_mthd();
5169#endif
5170
5171 if (authentication_success)
Channagoud Kadabiad259832015-05-29 11:14:17 -07005172 {
Mayank Grover70f8b0e2017-05-17 11:49:00 +05305173 is_allow_unlock = true;
5174 write_allow_oem_unlock(is_allow_unlock);
5175 ret = 0;
Channagoud Kadabiad259832015-05-29 11:14:17 -07005176 }
5177 return ret;
5178}
5179
Shashank Mittald3e54dd2014-08-28 15:24:02 -07005180void cmd_oem_lock(const char *arg, void *data, unsigned sz)
5181{
lijuang4ece1e72015-08-14 21:02:36 +08005182 set_device_unlock(UNLOCK, FALSE);
Shashank Mittal162244e2011-08-08 19:01:25 -07005183}
5184
Shashank Mittala0032282011-08-26 14:50:11 -07005185void cmd_oem_devinfo(const char *arg, void *data, unsigned sz)
5186{
lijuang511a2b52015-08-14 20:50:51 +08005187 char response[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005188 snprintf(response, sizeof(response), "\tDevice tampered: %s", (device.is_tampered ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07005189 fastboot_info(response);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005190 snprintf(response, sizeof(response), "\tDevice unlocked: %s", (device.is_unlocked ? "true" : "false"));
5191 fastboot_info(response);
Monika Singh292b3e92018-03-17 22:40:23 +05305192#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05305193 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05305194 {
5195 snprintf(response, sizeof(response), "\tDevice critical unlocked: %s",
5196 (device.is_unlock_critical ? "true" : "false"));
5197 fastboot_info(response);
5198 }
Parth Dixitddbc7352015-10-18 03:13:31 +05305199#endif
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005200 snprintf(response, sizeof(response), "\tCharger screen enabled: %s", (device.charger_screen_enabled ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07005201 fastboot_info(response);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305202 snprintf(response, sizeof(response), "\tDisplay panel: %s", (device.display_panel));
5203 fastboot_info(response);
tracychui9d60fc52020-06-05 17:31:38 +08005204#if defined(ENABLE_PRODINFO_ACCESS)
5205 snprintf(response, sizeof(response), "\tAdb enabled: %s", prod.is_adb_enabled ? "true" : "false");
5206 fastboot_info(response);
5207#endif
Shashank Mittala0032282011-08-26 14:50:11 -07005208 fastboot_okay("");
5209}
5210
lijuang511a2b52015-08-14 20:50:51 +08005211void cmd_flashing_get_unlock_ability(const char *arg, void *data, unsigned sz)
5212{
5213 char response[MAX_RSP_SIZE];
5214 snprintf(response, sizeof(response), "\tget_unlock_ability: %d", is_allow_unlock);
5215 fastboot_info(response);
5216 fastboot_okay("");
5217}
5218
5219void cmd_flashing_lock_critical(const char *arg, void *data, unsigned sz)
5220{
lijuang4ece1e72015-08-14 21:02:36 +08005221 set_device_unlock(UNLOCK_CRITICAL, FALSE);
lijuang511a2b52015-08-14 20:50:51 +08005222}
5223
5224void cmd_flashing_unlock_critical(const char *arg, void *data, unsigned sz)
5225{
lijuang4ece1e72015-08-14 21:02:36 +08005226 set_device_unlock(UNLOCK_CRITICAL, TRUE);
lijuang511a2b52015-08-14 20:50:51 +08005227}
5228
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07005229void cmd_preflash(const char *arg, void *data, unsigned sz)
5230{
5231 fastboot_okay("");
5232}
5233
Mao Flynn7b379f32015-04-20 00:28:30 +08005234static uint8_t logo_header[LOGO_IMG_HEADER_SIZE];
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305235
Mao Flynn7b379f32015-04-20 00:28:30 +08005236int splash_screen_check_header(logo_img_header *header)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305237{
Mao Flynn7b379f32015-04-20 00:28:30 +08005238 if (memcmp(header->magic, LOGO_IMG_MAGIC, 8))
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305239 return -1;
Mao Flynn7b379f32015-04-20 00:28:30 +08005240 if (header->width == 0 || header->height == 0)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305241 return -1;
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05305242 if (((header->blocks == 0) || (header->blocks > UINT_MAX/512))) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05305243 return -1;
5244 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305245 return 0;
5246}
5247
Mao Flynn7b379f32015-04-20 00:28:30 +08005248int splash_screen_flash()
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005249{
5250 struct ptentry *ptn;
5251 struct ptable *ptable;
Mao Flynn7b379f32015-04-20 00:28:30 +08005252 struct logo_img_header *header;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005253 struct fbcon_config *fb_display = NULL;
Channagoud Kadabib3ccf5c2014-12-03 12:39:29 -08005254
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305255 ptable = flash_get_ptable();
5256 if (ptable == NULL) {
Mao Flynn7b379f32015-04-20 00:28:30 +08005257 dprintf(CRITICAL, "ERROR: Partition table not found\n");
5258 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305259 }
Mao Flynn7b379f32015-04-20 00:28:30 +08005260
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305261 ptn = ptable_find(ptable, "splash");
5262 if (ptn == NULL) {
5263 dprintf(CRITICAL, "ERROR: splash Partition not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005264 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305265 }
Mao Flynn7b379f32015-04-20 00:28:30 +08005266 if (flash_read(ptn, 0, (void *)logo_header, LOGO_IMG_HEADER_SIZE)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305267 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005268 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305269 }
5270
Mao Flynn7b379f32015-04-20 00:28:30 +08005271 header = (struct logo_img_header *)logo_header;
5272 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305273 dprintf(CRITICAL, "ERROR: Boot image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005274 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305275 }
5276
5277 fb_display = fbcon_display();
5278 if (fb_display) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05305279 if (header->type &&
5280 ((header->blocks * 512) <= (fb_display->width *
5281 fb_display->height * (fb_display->bpp / 8)))) {
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05305282 /* RLE24 compressed data */
Mao Flynn7b379f32015-04-20 00:28:30 +08005283 uint8_t *base = (uint8_t *) fb_display->base + LOGO_IMG_OFFSET;
5284
5285 /* if the logo is full-screen size, remove "fbcon_clear()" */
5286 if ((header->width != fb_display->width)
5287 || (header->height != fb_display->height))
5288 fbcon_clear();
5289
5290 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
5291 (uint32_t *)base,
5292 (header->blocks * 512))) {
5293 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5294 return -1;
5295 }
5296 fbcon_extract_to_screen(header, base);
5297 return 0;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005298 }
Mao Flynn7b379f32015-04-20 00:28:30 +08005299
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07005300 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
5301 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005302 return -1;
5303 }
5304
Vineet Bajaj99291ed2014-09-09 12:29:46 +05305305 uint8_t *base = (uint8_t *) fb_display->base;
Sachin Bhayare619e9e42017-05-15 13:10:31 +05305306 uint32_t fb_size = ROUNDUP(fb_display->width *
5307 fb_display->height *
5308 (fb_display->bpp / 8), 4096);
5309 uint32_t splash_size = ((((header->width * header->height *
5310 fb_display->bpp/8) + 511) >> 9) << 9);
5311
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05305312 if ((header->height * header->width * (fb_display->bpp/8)) > (header->blocks * 512)) {
5313 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
5314 return -1;
5315 }
5316
Sachin Bhayare619e9e42017-05-15 13:10:31 +05305317 if (splash_size > fb_size) {
5318 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
5319 return -1;
5320 }
5321
Mao Flynn7b379f32015-04-20 00:28:30 +08005322 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
5323 (uint32_t *)base,
5324 ((((header->width * header->height * fb_display->bpp/8) + 511) >> 9) << 9))) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305325 fbcon_clear();
Vineet Bajaj99291ed2014-09-09 12:29:46 +05305326 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005327 return -1;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005328 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305329 }
5330
Mao Flynn7b379f32015-04-20 00:28:30 +08005331 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305332}
5333
Mao Flynn7b379f32015-04-20 00:28:30 +08005334int splash_screen_mmc()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305335{
5336 int index = INVALID_PTN;
5337 unsigned long long ptn = 0;
5338 struct fbcon_config *fb_display = NULL;
Mao Flynn7b379f32015-04-20 00:28:30 +08005339 struct logo_img_header *header;
Mao Flynn1893a7f2015-06-03 12:03:36 +08005340 uint32_t blocksize, realsize, readsize;
5341 uint8_t *base;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305342
5343 index = partition_get_index("splash");
5344 if (index == 0) {
5345 dprintf(CRITICAL, "ERROR: splash Partition table not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005346 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305347 }
5348
5349 ptn = partition_get_offset(index);
5350 if (ptn == 0) {
5351 dprintf(CRITICAL, "ERROR: splash Partition invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005352 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305353 }
5354
Mao Flynn1893a7f2015-06-03 12:03:36 +08005355 mmc_set_lun(partition_get_lun(index));
5356
5357 blocksize = mmc_get_device_blocksize();
5358 if (blocksize == 0) {
5359 dprintf(CRITICAL, "ERROR:splash Partition invalid blocksize\n");
5360 return -1;
5361 }
5362
5363 fb_display = fbcon_display();
Channagoud Kadabidaf10a62015-07-22 11:51:55 -07005364 if (!fb_display)
5365 {
5366 dprintf(CRITICAL, "ERROR: fb config is not allocated\n");
5367 return -1;
5368 }
5369
Mao Flynn1893a7f2015-06-03 12:03:36 +08005370 base = (uint8_t *) fb_display->base;
5371
jialongjhan2769d202020-05-22 18:25:56 +08005372 if (mmc_read(ptn , (uint32_t *)(base + LOGO_IMG_OFFSET), blocksize)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305373 dprintf(CRITICAL, "ERROR: Cannot read splash image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005374 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305375 }
Mao Flynn1893a7f2015-06-03 12:03:36 +08005376 header = (struct logo_img_header *)(base + LOGO_IMG_OFFSET);
Mao Flynn7b379f32015-04-20 00:28:30 +08005377 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305378 dprintf(CRITICAL, "ERROR: Splash image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08005379 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305380 }
5381
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305382 if (fb_display) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05305383 if (header->type &&
Ashish Bhimanpalliwarce39f482020-10-06 15:27:37 +05305384 (((UINT_MAX - LOGO_IMG_HEADER_SIZE) / 512) >= header->blocks) &&
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05305385 ((header->blocks * 512) <= (fb_display->width *
5386 fb_display->height * (fb_display->bpp / 8)))) {
5387 /* 1 RLE24 compressed data */
Mao Flynn1893a7f2015-06-03 12:03:36 +08005388 base += LOGO_IMG_OFFSET;
Mao Flynn7b379f32015-04-20 00:28:30 +08005389
Mao Flynn1893a7f2015-06-03 12:03:36 +08005390 realsize = header->blocks * 512;
5391 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
5392
5393 /* if the logo is not full-screen size, clean screen */
Mao Flynn7b379f32015-04-20 00:28:30 +08005394 if ((header->width != fb_display->width)
5395 || (header->height != fb_display->height))
5396 fbcon_clear();
5397
Sachin Bhayare619e9e42017-05-15 13:10:31 +05305398 uint32_t fb_size = ROUNDUP(fb_display->width *
5399 fb_display->height *
5400 (fb_display->bpp / 8), 4096);
5401
5402 if (readsize > fb_size) {
5403 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
5404 return -1;
5405 }
5406
jialongjhan2769d202020-05-22 18:25:56 +08005407 if (mmc_read(ptn + blocksize, (uint32_t *)(base + blocksize), readsize)) {
Mao Flynn7b379f32015-04-20 00:28:30 +08005408 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5409 return -1;
5410 }
Mao Flynn7b379f32015-04-20 00:28:30 +08005411
Mao Flynn1893a7f2015-06-03 12:03:36 +08005412 fbcon_extract_to_screen(header, (base + LOGO_IMG_HEADER_SIZE));
5413 } else { /* 2 Raw BGR data */
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305414
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07005415 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
5416 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn1893a7f2015-06-03 12:03:36 +08005417 return -1;
5418 }
5419
5420 realsize = header->width * header->height * fb_display->bpp / 8;
5421 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05305422 if (realsize > (header->blocks * 512)) {
5423 dprintf(CRITICAL, "Logo Size error\n");
5424 return -1;
5425 }
Mao Flynn1893a7f2015-06-03 12:03:36 +08005426
5427 if (blocksize == LOGO_IMG_HEADER_SIZE) { /* read the content directly */
Kishor PKee5c0a32018-03-06 16:49:46 +05305428 if (mmc_read((ptn + PLL_CODES_OFFSET + LOGO_IMG_HEADER_SIZE), (uint32_t *)base, readsize)) {
Mao Flynn1893a7f2015-06-03 12:03:36 +08005429 fbcon_clear();
5430 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5431 return -1;
5432 }
5433 } else {
Kishor PKee5c0a32018-03-06 16:49:46 +05305434 if (mmc_read(ptn + PLL_CODES_OFFSET + blocksize ,
Mao Flynn1893a7f2015-06-03 12:03:36 +08005435 (uint32_t *)(base + LOGO_IMG_OFFSET + blocksize), readsize)) {
5436 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5437 return -1;
5438 }
5439 memmove(base, (base + LOGO_IMG_OFFSET + LOGO_IMG_HEADER_SIZE), realsize);
5440 }
5441 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305442 }
5443
Mao Flynn7b379f32015-04-20 00:28:30 +08005444 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305445}
5446
Mao Flynn7b379f32015-04-20 00:28:30 +08005447int fetch_image_from_partition()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305448{
5449 if (target_is_emmc_boot()) {
5450 return splash_screen_mmc();
5451 } else {
5452 return splash_screen_flash();
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005453 }
5454}
5455
Mayank Grover351a75e2017-05-30 20:06:08 +05305456void publish_getvar_multislot_vars()
5457{
5458 int i,count;
5459 static bool published = false;
5460 static char slot_count[MAX_RSP_SIZE];
5461 static struct ab_slot_info slot_info[AB_SUPPORTED_SLOTS];
5462 static char active_slot_suffix[MAX_RSP_SIZE];
5463 static char has_slot_pname[NUM_PARTITIONS][MAX_GET_VAR_NAME_SIZE];
5464 static char has_slot_reply[NUM_PARTITIONS][MAX_RSP_SIZE];
5465 const char *tmp;
5466 char tmpbuff[MAX_GET_VAR_NAME_SIZE];
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305467 signed active_slt;
Mayank Grover351a75e2017-05-30 20:06:08 +05305468
5469 if (!published)
5470 {
5471 /* Update slot meta info */
5472 count = partition_fill_partition_meta(has_slot_pname, has_slot_reply,
5473 partition_get_partition_count());
5474 for(i=0; i<count; i++)
5475 {
5476 memset(tmpbuff, 0, MAX_GET_VAR_NAME_SIZE);
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305477 snprintf(tmpbuff, MAX_GET_VAR_NAME_SIZE,"has-slot:%s",
5478 has_slot_pname[i]);
5479 strlcpy(has_slot_pname[i], tmpbuff, MAX_GET_VAR_NAME_SIZE);
Mayank Grover351a75e2017-05-30 20:06:08 +05305480 fastboot_publish(has_slot_pname[i], has_slot_reply[i]);
5481 }
5482
5483 for (i=0; i<AB_SUPPORTED_SLOTS; i++)
5484 {
5485 tmp = SUFFIX_SLOT(i);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305486 tmp++; // to remove "_" from slot_suffix.
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305487 snprintf(slot_info[i].slot_is_unbootable, sizeof(slot_info[i].slot_is_unbootable),
5488 "slot-unbootable:%s", tmp);
5489 snprintf(slot_info[i].slot_is_active, sizeof(slot_info[i].slot_is_active),
5490 "slot-active:%s", tmp);
5491 snprintf(slot_info[i].slot_is_succesful, sizeof(slot_info[i].slot_is_succesful),
5492 "slot-success:%s", tmp);
5493 snprintf(slot_info[i].slot_retry_count, sizeof(slot_info[i].slot_retry_count),
5494 "slot-retry-count:%s", tmp);
Mayank Grover351a75e2017-05-30 20:06:08 +05305495 fastboot_publish(slot_info[i].slot_is_unbootable,
5496 slot_info[i].slot_is_unbootable_rsp);
5497 fastboot_publish(slot_info[i].slot_is_active,
5498 slot_info[i].slot_is_active_rsp);
5499 fastboot_publish(slot_info[i].slot_is_succesful,
5500 slot_info[i].slot_is_succesful_rsp);
5501 fastboot_publish(slot_info[i].slot_retry_count,
5502 slot_info[i].slot_retry_count_rsp);
5503 }
5504 fastboot_publish("current-slot", active_slot_suffix);
5505 snprintf(slot_count, sizeof(slot_count),"%d", AB_SUPPORTED_SLOTS);
5506 fastboot_publish("slot-count", slot_count);
5507 published = true;
5508 }
5509
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305510 active_slt = partition_find_active_slot();
5511 if (active_slt != INVALID)
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305512 {
5513 tmp = SUFFIX_SLOT(active_slt);
5514 tmp++; // to remove "_" from slot_suffix.
5515 snprintf(active_slot_suffix, sizeof(active_slot_suffix), "%s", tmp);
5516 }
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305517 else
5518 strlcpy(active_slot_suffix, "INVALID", sizeof(active_slot_suffix));
5519
Mayank Grover351a75e2017-05-30 20:06:08 +05305520 /* Update partition meta information */
5521 partition_fill_slot_meta(slot_info);
5522 return;
5523}
5524
lijuang4ece1e72015-08-14 21:02:36 +08005525void get_product_name(unsigned char *buf)
5526{
5527 snprintf((char*)buf, MAX_RSP_SIZE, "%s", TARGET(BOARD));
5528 return;
5529}
5530
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305531#if PRODUCT_IOT
5532void get_bootloader_version_iot(unsigned char *buf)
5533{
5534 if (buf != NULL)
5535 {
5536 strlcpy(buf, TARGET(BOARD), MAX_VERSION_LEN);
5537 strlcat(buf, "-", MAX_VERSION_LEN);
5538 strlcat(buf, PRODUCT_IOT_VERSION, MAX_VERSION_LEN);
5539 }
5540 return;
5541}
5542#endif
5543
lijuang4ece1e72015-08-14 21:02:36 +08005544void get_bootloader_version(unsigned char *buf)
5545{
jhchena8a15dd2020-04-24 15:45:57 +08005546 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.bootloader_version);
lijuang4ece1e72015-08-14 21:02:36 +08005547 return;
5548}
5549
5550void get_baseband_version(unsigned char *buf)
5551{
jhchena8a15dd2020-04-24 15:45:57 +08005552 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.radio_version);
lijuang4ece1e72015-08-14 21:02:36 +08005553 return;
5554}
5555
Monika Singh32a09f72018-03-14 13:08:29 +05305556bool is_device_locked_critical()
5557{
5558 return device.is_unlock_critical ? false:true;
5559}
5560
lijuang4ece1e72015-08-14 21:02:36 +08005561bool is_device_locked()
5562{
5563 return device.is_unlocked ? false:true;
5564}
5565
Monika Singh32a09f72018-03-14 13:08:29 +05305566bool is_verity_enforcing()
5567{
5568 return device.verity_mode ? true:false;
5569}
5570
Amol Jadi5edf3552013-07-23 14:15:34 -07005571/* register commands and variables for fastboot */
5572void aboot_fastboot_register_commands(void)
5573{
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005574 int i;
lijuangf16461c2015-08-03 17:09:34 +08005575 char hw_platform_buf[MAX_RSP_SIZE];
Rahul Shaharee7baede2021-02-02 13:23:57 +05305576 VirtualAbMergeStatus SnapshotMergeStatus;
Amol Jadi5edf3552013-07-23 14:15:34 -07005577
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005578 struct fastboot_cmd_desc cmd_list[] = {
lijuang511a2b52015-08-14 20:50:51 +08005579 /* By default the enabled list is empty. */
5580 {"", NULL},
5581 /* move commands enclosed within the below ifndef to here
5582 * if they need to be enabled in user build.
5583 */
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005584#ifndef DISABLE_FASTBOOT_CMDS
lijuang511a2b52015-08-14 20:50:51 +08005585 /* Register the following commands only for non-user builds */
5586 {"flash:", cmd_flash},
5587 {"erase:", cmd_erase},
5588 {"boot", cmd_boot},
5589 {"continue", cmd_continue},
5590 {"reboot", cmd_reboot},
5591 {"reboot-bootloader", cmd_reboot_bootloader},
5592 {"oem unlock", cmd_oem_unlock},
5593 {"oem unlock-go", cmd_oem_unlock_go},
5594 {"oem lock", cmd_oem_lock},
5595 {"flashing unlock", cmd_oem_unlock},
5596 {"flashing lock", cmd_oem_lock},
5597 {"flashing lock_critical", cmd_flashing_lock_critical},
5598 {"flashing unlock_critical", cmd_flashing_unlock_critical},
5599 {"flashing get_unlock_ability", cmd_flashing_get_unlock_ability},
5600 {"oem device-info", cmd_oem_devinfo},
5601 {"preflash", cmd_preflash},
5602 {"oem enable-charger-screen", cmd_oem_enable_charger_screen},
5603 {"oem disable-charger-screen", cmd_oem_disable_charger_screen},
lijuanga25d8bb2015-09-16 13:11:52 +08005604 {"oem off-mode-charge", cmd_oem_off_mode_charger},
lijuang511a2b52015-08-14 20:50:51 +08005605 {"oem select-display-panel", cmd_oem_select_display_panel},
Mayank Grover6ccc1c92017-07-04 17:36:46 +05305606 {"set_active",cmd_set_active},
Mayank Grover98c4c742019-04-25 17:21:37 +05305607 {"reboot-fastboot",cmd_reboot_fastboot},
5608 {"reboot-recovery",cmd_reboot_recovery},
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05305609#ifdef VIRTUAL_AB_OTA
5610 {"snapshot-update", CmdUpdateSnapshot},
5611#endif
Channagoud Kadabi736c4962015-08-21 11:56:52 -07005612#if UNITTEST_FW_SUPPORT
Channagoud Kadabid5ddf482015-09-28 10:31:35 -07005613 {"oem run-tests", cmd_oem_runtests},
Channagoud Kadabi736c4962015-08-21 11:56:52 -07005614#endif
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005615#endif
tracychui9d60fc52020-06-05 17:31:38 +08005616#if defined(ENABLE_PRODINFO_ACCESS)
5617 {"oem adb_enable", CmdOemEnableAdb},
5618#endif
lijuang511a2b52015-08-14 20:50:51 +08005619 };
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005620
5621 int fastboot_cmds_count = sizeof(cmd_list)/sizeof(cmd_list[0]);
5622 for (i = 1; i < fastboot_cmds_count; i++)
5623 fastboot_register(cmd_list[i].name,cmd_list[i].cb);
5624
Amol Jadi5edf3552013-07-23 14:15:34 -07005625 /* publish variables and their values */
5626 fastboot_publish("product", TARGET(BOARD));
5627 fastboot_publish("kernel", "lk");
5628 fastboot_publish("serialno", sn_buf);
5629
Mayank Grovera64dfbe2018-05-17 14:06:34 +05305630 /*publish hw-revision major(upper 16 bits) and minor(lower 16 bits)*/
5631 snprintf(soc_version_str, MAX_RSP_SIZE, "%x", board_soc_version());
5632 fastboot_publish("hw-revision", soc_version_str);
5633
Amol Jadi5edf3552013-07-23 14:15:34 -07005634 /*
5635 * partition info is supported only for emmc partitions
5636 * Calling this for NAND prints some error messages which
5637 * is harmless but misleading. Avoid calling this for NAND
5638 * devices.
5639 */
5640 if (target_is_emmc_boot())
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305641 publish_getvar_partition_info(part_info, partition_get_partition_count());
Amol Jadi5edf3552013-07-23 14:15:34 -07005642
Mayank Grover351a75e2017-05-30 20:06:08 +05305643 if (partition_multislot_is_supported())
5644 publish_getvar_multislot_vars();
5645
Amol Jadi5edf3552013-07-23 14:15:34 -07005646 /* Max download size supported */
lijuang2fbed912019-07-12 14:15:05 +08005647#if !VERIFIED_BOOT_2
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005648 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5649 target_get_max_flash_size());
lijuang2fbed912019-07-12 14:15:05 +08005650#else
5651 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5652 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5653#endif
5654
Amol Jadi5edf3552013-07-23 14:15:34 -07005655 fastboot_publish("max-download-size", (const char *) max_download_size);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005656 /* Is the charger screen check enabled */
5657 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
5658 device.charger_screen_enabled);
5659 fastboot_publish("charger-screen-enabled",
5660 (const char *) charger_screen_enabled);
tracychui9d60fc52020-06-05 17:31:38 +08005661#if defined(ENABLE_PRODINFO_ACCESS)
5662 read_prod_info(&prod);
5663 snprintf(AdbEnable, MAX_RSP_SIZE, "%d",
5664 prod.is_adb_enabled);
5665 fastboot_publish("adb-enabled",
5666 (const char *) AdbEnable);
5667#endif
lijuanga25d8bb2015-09-16 13:11:52 +08005668 fastboot_publish("off-mode-charge", (const char *) charger_screen_enabled);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305669 snprintf(panel_display_mode, MAX_RSP_SIZE, "%s",
5670 device.display_panel);
5671 fastboot_publish("display-panel",
5672 (const char *) panel_display_mode);
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +05305673
5674 if (target_is_emmc_boot())
5675 {
5676 mmc_blocksize = mmc_get_device_blocksize();
5677 }
5678 else
5679 {
5680 mmc_blocksize = flash_block_size();
5681 }
5682 snprintf(block_size_string, MAX_RSP_SIZE, "0x%x", mmc_blocksize);
5683 fastboot_publish("erase-block-size", (const char *) block_size_string);
5684 fastboot_publish("logical-block-size", (const char *) block_size_string);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305685#if PRODUCT_IOT
5686 get_bootloader_version_iot(&bootloader_version_string);
5687 fastboot_publish("version-bootloader", (const char *) bootloader_version_string);
5688
5689 /* Version baseband is n/a for apq iot devices */
5690 fastboot_publish("version-baseband", "N/A");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305691#else
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08005692 fastboot_publish("version-bootloader", (const char *) device.bootloader_version);
5693 fastboot_publish("version-baseband", (const char *) device.radio_version);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305694#endif
lijuangf16461c2015-08-03 17:09:34 +08005695 fastboot_publish("secure", is_secure_boot_enable()? "yes":"no");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305696 fastboot_publish("unlocked", device.is_unlocked ? "yes":"no");
lijuangf16461c2015-08-03 17:09:34 +08005697 smem_get_hw_platform_name((unsigned char *) hw_platform_buf, sizeof(hw_platform_buf));
5698 snprintf(get_variant, MAX_RSP_SIZE, "%s %s", hw_platform_buf,
5699 target_is_emmc_boot()? "eMMC":"UFS");
5700 fastboot_publish("variant", (const char *) get_variant);
lijuang65c5a822015-08-29 16:35:36 +08005701#if CHECK_BAT_VOLTAGE
lijuang102dfa92015-10-09 18:31:03 +08005702 update_battery_status();
lijuang65c5a822015-08-29 16:35:36 +08005703 fastboot_publish("battery-voltage", (const char *) battery_voltage);
lijuang102dfa92015-10-09 18:31:03 +08005704 fastboot_publish("battery-soc-ok", (const char *) battery_soc_ok);
lijuang65c5a822015-08-29 16:35:36 +08005705#endif
Luca Weiss7f063f12022-04-14 11:06:43 +02005706 fastboot_publish("is-userspace", "no");
Rahul Shaharee7baede2021-02-02 13:23:57 +05305707
5708 if (target_virtual_ab_supported()) {
5709 SnapshotMergeStatus = GetSnapshotMergeStatus ();
5710
5711 switch (SnapshotMergeStatus) {
5712 case SNAPSHOTTED:
5713 SnapshotMergeStatus = SNAPSHOTTED;
5714 break;
5715 case MERGING:
5716 SnapshotMergeStatus = MERGING;
5717 break;
5718 default:
5719 SnapshotMergeStatus = NONE_MERGE_STATUS;
5720 break;
5721 }
5722
5723 snprintf(SnapshotMergeState,
5724 strlen(VabSnapshotMergeStatus[SnapshotMergeStatus]) + 1,
5725 "%s", VabSnapshotMergeStatus[SnapshotMergeStatus]);
5726 fastboot_publish("snapshot-update-state", SnapshotMergeState);
5727 }
Amol Jadi5edf3552013-07-23 14:15:34 -07005728}
5729
Brian Swetland9c4c0752009-01-25 16:23:50 -08005730void aboot_init(const struct app_descriptor *app)
5731{
Shashank Mittal4f99a882010-02-01 13:58:50 -08005732 unsigned reboot_mode = 0;
Mayank Grover351a75e2017-05-30 20:06:08 +05305733 int boot_err_type = 0;
5734 int boot_slot = INVALID;
jessicatseng43b1e352020-05-26 13:17:56 +08005735 int vbat = 0;
5736 char boot_vbat[MAX_RSP_SIZE];
Chandan Uddarajubedca152010-06-02 23:05:15 -07005737
lijuang39831732016-01-08 17:49:02 +08005738 /* Initialise wdog to catch early lk crashes */
5739#if WDOG_SUPPORT
5740 msm_wdog_init();
5741#endif
5742
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005743 /* Setup page size information for nv storage */
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005744 if (target_is_emmc_boot())
5745 {
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005746 page_size = mmc_page_size();
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005747 page_mask = page_size - 1;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05305748 mmc_blocksize = mmc_get_device_blocksize();
5749 mmc_blocksize_mask = mmc_blocksize - 1;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005750 }
5751 else
5752 {
5753 page_size = flash_page_size();
5754 page_mask = page_size - 1;
5755 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07005756 ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
5757
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005758 read_device_info(&device);
tracychui9d60fc52020-06-05 17:31:38 +08005759#if defined(ENABLE_PRODINFO_ACCESS)
5760 read_prod_info(&prod);
5761#endif
vijay kumarc65876c2015-04-24 13:29:16 +05305762 read_allow_oem_unlock(&device);
Shashank Mittal162244e2011-08-08 19:01:25 -07005763
Mayank Grover351a75e2017-05-30 20:06:08 +05305764 /* Detect multi-slot support */
5765 if (partition_multislot_is_supported())
5766 {
5767 boot_slot = partition_find_active_slot();
5768 if (boot_slot == INVALID)
5769 {
5770 boot_into_fastboot = true;
5771 dprintf(INFO, "Active Slot: (INVALID)\n");
5772 }
5773 else
5774 {
5775 /* Setting the state of system to boot active slot */
5776 partition_mark_active_slot(boot_slot);
5777 dprintf(INFO, "Active Slot: (%s)\n", SUFFIX_SLOT(boot_slot));
5778 }
5779 }
5780
Greg Griscod6250552011-06-29 14:40:23 -07005781 target_serialno((unsigned char *) sn_buf);
tracychui9d60fc52020-06-05 17:31:38 +08005782#if defined(ENABLE_PRODINFO_ACCESS)
5783 dprintf(CRITICAL,"serial number: %s\n",sn_buf);
5784#else
Ajay Dudanib06c05f2011-05-12 14:46:10 -07005785 dprintf(SPEW,"serial number: %s\n",sn_buf);
tracychui9d60fc52020-06-05 17:31:38 +08005786#endif
5787#if defined(ENABLE_PRODINFO_ACCESS)
5788 read_prod_info(&prod);
5789 snprintf((char *)cust_sn_buf, PRODINFO_MAX_SSN_LEN + 1, "%s", prod.ssn);
5790 dprintf(CRITICAL,"customer serial number: %s\n", cust_sn_buf);
5791 snprintf((char *)factory_sn_buf, PRODINFO_MAX_ISN_LEN + 1, "%s", prod.isn);
5792 dprintf(CRITICAL,"factory serial number: %s\n", factory_sn_buf);
5793#endif
Dhaval Patel223ec952013-07-18 14:49:44 -07005794 memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE);
5795
Matthew Qindefd5562014-07-11 18:02:40 +08005796 /*
5797 * Check power off reason if user force reset,
5798 * if yes phone will do normal boot.
5799 */
5800 if (is_user_force_reset())
5801 goto normal_boot;
5802
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005803 /* Check if we should do something other than booting up */
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005804 if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005805 {
Pavel Nedeva4c9d3a2013-05-15 14:42:34 +03005806 dprintf(ALWAYS,"dload mode key sequence detected\n");
lijuang395b5e62015-11-19 17:39:44 +08005807 reboot_device(EMERGENCY_DLOAD);
5808 dprintf(CRITICAL,"Failed to reboot into dload mode\n");
5809
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005810 boot_into_fastboot = true;
5811 }
5812 if (!boot_into_fastboot)
5813 {
5814 if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
5815 boot_into_recovery = 1;
5816 if (!boot_into_recovery &&
5817 (keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
Pavel Nedev5d91d412013-04-29 11:34:24 +03005818 boot_into_fastboot = true;
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005819 }
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005820 #if NO_KEYPAD_DRIVER
Kinson Chik0b1c8162011-08-31 16:31:57 -07005821 if (fastboot_trigger())
Pavel Nedev5d91d412013-04-29 11:34:24 +03005822 boot_into_fastboot = true;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005823 #endif
Chandan Uddarajubedca152010-06-02 23:05:15 -07005824
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005825#if USE_PON_REBOOT_REG
5826 reboot_mode = check_hard_reboot_mode();
5827#else
Ajay Dudani77421292010-10-27 19:34:06 -07005828 reboot_mode = check_reboot_mode();
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005829#endif
5830 if (reboot_mode == RECOVERY_MODE)
5831 {
Ajay Dudani77421292010-10-27 19:34:06 -07005832 boot_into_recovery = 1;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005833 }
5834 else if(reboot_mode == FASTBOOT_MODE)
5835 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005836 boot_into_fastboot = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005837 }
5838 else if(reboot_mode == ALARM_BOOT)
5839 {
Matthew Qind886f3c2014-01-17 16:52:01 +08005840 boot_reason_alarm = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005841 }
Monika Singhb0db4b82018-09-26 12:18:02 +05305842#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05305843 else if (VB_M <= target_get_vb_version())
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005844 {
Mayank Grover889be1b2017-09-12 20:12:23 +05305845 if (reboot_mode == DM_VERITY_ENFORCING)
5846 {
5847 device.verity_mode = 1;
5848 write_device_info(&device);
5849 }
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005850#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05305851 else if (reboot_mode == DM_VERITY_EIO)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005852#else
Mayank Grover889be1b2017-09-12 20:12:23 +05305853 else if (reboot_mode == DM_VERITY_LOGGING)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005854#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05305855 {
5856 device.verity_mode = 0;
5857 write_device_info(&device);
5858 }
5859 else if (reboot_mode == DM_VERITY_KEYSCLEAR)
5860 {
5861 if(send_delete_keys_to_tz())
5862 ASSERT(0);
5863 }
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005864 }
Parth Dixitddbc7352015-10-18 03:13:31 +05305865#endif
Ajay Dudani77421292010-10-27 19:34:06 -07005866
jialongjhan2769d202020-05-22 18:25:56 +08005867 /* Display splash screen if enabled */
5868#if DISPLAY_SPLASH_SCREEN
5869#if NO_ALARM_DISPLAY
5870 if (!check_alarm_boot()) {
5871#endif
5872 dprintf(SPEW, "Display Init: Start\n");
5873#if DISPLAY_HDMI_PRIMARY
5874 if (!strlen(device.display_panel))
5875 strlcpy(device.display_panel, DISPLAY_PANEL_HDMI,
5876 sizeof(device.display_panel));
5877#endif
5878#if ENABLE_WBC
5879 /* Wait if the display shutdown is in progress */
5880 while(pm_app_display_shutdown_in_prgs());
5881 if (!pm_appsbl_display_init_done())
5882 target_display_init(device.display_panel);
5883 else
5884 display_image_on_screen();
5885#else
5886 target_display_init(device.display_panel);
5887#endif
5888 dprintf(SPEW, "Display Init: Done\n");
5889#if NO_ALARM_DISPLAY
5890 }
5891#endif
5892#endif
5893
5894
Matthew Qindefd5562014-07-11 18:02:40 +08005895normal_boot:
Pavel Nedev5d91d412013-04-29 11:34:24 +03005896 if (!boot_into_fastboot)
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005897 {
jessicatseng43b1e352020-05-26 13:17:56 +08005898 if(!target_pause_for_battery_charge())
5899 {
5900 vbat = target_get_battery_voltage();
5901 snprintf(boot_vbat, MAX_RSP_SIZE, "%d", vbat);
5902 dprintf(CRITICAL,"battery_voltage: %s\n", boot_vbat);
5903 if(vbat < 3500000)
5904 {
5905 display_lowbattery_image_on_screen();
5906 //[Arima][8901][JialongJhan] Command mode reflash screen when low battery logo shown 20190516 Start
5907 msm_display_flush();
5908 //[Arima][8901][JialongJhan] Command mode reflash screen when low battery logo shown 20190516 End
5909 dprintf(CRITICAL,"Low battery, cannot boot up...\n");
5910 mdelay(3000);
5911 shutdown_device();
5912 }
5913 }
5914
Pavel Nedev5d91d412013-04-29 11:34:24 +03005915 if (target_is_emmc_boot())
Shashank Mittala0032282011-08-26 14:50:11 -07005916 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005917 if(emmc_recovery_init())
5918 dprintf(ALWAYS,"error in emmc_recovery_init\n");
5919 if(target_use_signed_kernel())
Shashank Mittala0032282011-08-26 14:50:11 -07005920 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005921 if((device.is_unlocked) || (device.is_tampered))
5922 {
5923 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05305924 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Pavel Nedev5d91d412013-04-29 11:34:24 +03005925 #endif
5926 #if USE_PCOM_SECBOOT
5927 set_tamper_flag(device.is_tampered);
5928 #endif
5929 }
Shashank Mittala0032282011-08-26 14:50:11 -07005930 }
Amit Blay6281ebc2015-01-11 14:44:08 +02005931
Mayank Grover351a75e2017-05-30 20:06:08 +05305932retry_boot:
5933 /* Trying to boot active partition */
5934 if (partition_multislot_is_supported())
5935 {
5936 boot_slot = partition_find_boot_slot();
5937 partition_mark_active_slot(boot_slot);
5938 if (boot_slot == INVALID)
5939 goto fastboot;
5940 }
5941
5942 boot_err_type = boot_linux_from_mmc();
5943 switch (boot_err_type)
5944 {
5945 case ERR_INVALID_PAGE_SIZE:
5946 case ERR_DT_PARSE:
5947 case ERR_ABOOT_ADDR_OVERLAP:
Mayank Grover10cabbe2017-10-30 19:11:05 +05305948 case ERR_INVALID_BOOT_MAGIC:
Mayank Grover351a75e2017-05-30 20:06:08 +05305949 if(partition_multislot_is_supported())
Mayank Grover10cabbe2017-10-30 19:11:05 +05305950 {
5951 /*
5952 * Deactivate current slot, as it failed to
5953 * boot, and retry next slot.
5954 */
5955 partition_deactivate_slot(boot_slot);
Mayank Grover351a75e2017-05-30 20:06:08 +05305956 goto retry_boot;
Mayank Grover10cabbe2017-10-30 19:11:05 +05305957 }
Mayank Grover351a75e2017-05-30 20:06:08 +05305958 else
5959 break;
Mayank Grover351a75e2017-05-30 20:06:08 +05305960 default:
5961 break;
5962 /* going to fastboot menu */
5963 }
Shashank Mittala0032282011-08-26 14:50:11 -07005964 }
Pavel Nedev5d91d412013-04-29 11:34:24 +03005965 else
5966 {
5967 recovery_init();
5968 #if USE_PCOM_SECBOOT
5969 if((device.is_unlocked) || (device.is_tampered))
5970 set_tamper_flag(device.is_tampered);
5971 #endif
5972 boot_linux_from_flash();
5973 }
5974 dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
5975 "to fastboot mode.\n");
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005976 }
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005977
Mayank Grover351a75e2017-05-30 20:06:08 +05305978fastboot:
jialongjhan2769d202020-05-22 18:25:56 +08005979
5980 mdelay(1000);
5981
Amol Jadi5edf3552013-07-23 14:15:34 -07005982 /* We are here means regular boot did not happen. Start fastboot. */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07005983
Amol Jadi5edf3552013-07-23 14:15:34 -07005984 /* register aboot specific fastboot commands */
5985 aboot_fastboot_register_commands();
Amol Jadi57abe4c2011-05-24 15:47:27 -07005986
Amol Jadi5edf3552013-07-23 14:15:34 -07005987 /* dump partition table for debug info */
Kinson Chikf1a43512011-07-14 11:28:39 -07005988 partition_dump();
Amol Jadi5edf3552013-07-23 14:15:34 -07005989
5990 /* initialize and start fastboot */
Saranya Chidura41b34532018-10-16 12:29:52 +05305991#if !VERIFIED_BOOT_2
Amol Jadi5edf3552013-07-23 14:15:34 -07005992 fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
Saranya Chidura41b34532018-10-16 12:29:52 +05305993#else
5994 /* Add salt buffer offset at start of image address to copy VB salt */
5995 fastboot_init(ADD_SALT_BUFF_OFFSET(target_get_scratch_address()),
5996 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5997#endif
lijuang4ece1e72015-08-14 21:02:36 +08005998#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08005999 display_fastboot_menu();
lijuang4ece1e72015-08-14 21:02:36 +08006000#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08006001}
6002
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07006003uint32_t get_page_size()
6004{
6005 return page_size;
6006}
6007
Amir Samuelov57a6fa22013-06-05 16:36:43 +03006008/*
6009 * Calculated and save hash (SHA256) for non-signed boot image.
6010 *
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07006011 * @param image_addr - Boot image address
6012 * @param image_size - Size of the boot image
Amir Samuelov57a6fa22013-06-05 16:36:43 +03006013 *
6014 * @return int - 0 on success, negative value on failure.
6015 */
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07006016static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size)
Amir Samuelov57a6fa22013-06-05 16:36:43 +03006017{
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07006018 unsigned int digest[8];
6019#if IMAGE_VERIF_ALGO_SHA1
6020 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
6021#else
6022 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
6023#endif
Amir Samuelov57a6fa22013-06-05 16:36:43 +03006024
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07006025 target_crypto_init_params();
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08006026 hash_find((unsigned char *) image_addr, image_size, (unsigned char *)&digest, auth_algo);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03006027
6028 save_kernel_hash_cmd(digest);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07006029 dprintf(INFO, "aboot_save_boot_hash_mmc: imagesize_actual size %d bytes.\n", (int) image_size);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03006030
6031 return 0;
6032}
6033
Mayank Grover351a75e2017-05-30 20:06:08 +05306034
Brian Swetland9c4c0752009-01-25 16:23:50 -08006035APP_START(aboot)
6036 .init = aboot_init,
6037APP_END