blob: 584ba35f110655c1fba38773a7a58050b971bf8b [file] [log] [blame]
Brian Swetland9c4c0752009-01-25 16:23:50 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
4 *
Mayank Grover98c4c742019-04-25 17:21:37 +05305 * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved.
Brian Swetland9c4c0752009-01-25 16:23:50 -08006 *
Chandan Uddaraju5fa471a2009-12-02 17:31:34 -08007 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070014 * * Neither the name of The Linux Foundation nor
Chandan Uddaraju5fa471a2009-12-02 17:31:34 -080015 * the names of its contributors may be used to endorse or promote
16 * products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
Brian Swetland9c4c0752009-01-25 16:23:50 -080031 */
32
33#include <app.h>
34#include <debug.h>
35#include <arch/arm.h>
Brian Swetland9c4c0752009-01-25 16:23:50 -080036#include <string.h>
Channagoud Kadabi132ff552013-04-19 14:34:44 -070037#include <stdlib.h>
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -070038#include <limits.h>
Brian Swetland9c4c0752009-01-25 16:23:50 -080039#include <kernel/thread.h>
40#include <arch/ops.h>
41
Dima Zavin214cc642009-01-26 11:16:21 -080042#include <dev/flash.h>
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +020043#include <dev/flash-ubi.h>
Dima Zavin214cc642009-01-26 11:16:21 -080044#include <lib/ptable.h>
Dima Zavinb4283602009-01-26 16:36:57 -080045#include <dev/keys.h>
Shashank Mittal4f99a882010-02-01 13:58:50 -080046#include <dev/fbcon.h>
Ajay Dudanid04110c2011-01-17 23:55:07 -080047#include <baseband.h>
Greg Griscod6250552011-06-29 14:40:23 -070048#include <target.h>
49#include <mmc.h>
Kinson Chikf1a43512011-07-14 11:28:39 -070050#include <partition_parser.h>
Mayank Grover351a75e2017-05-30 20:06:08 +053051#include <ab_partition_parser.h>
Monika Singh292b3e92018-03-17 22:40:23 +053052#include <verifiedboot.h>
Greg Griscod6250552011-06-29 14:40:23 -070053#include <platform.h>
Shashank Mittalcd98d472011-08-02 14:29:24 -070054#include <crypto_hash.h>
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070055#include <malloc.h>
Amol Jadi492d5a52013-03-15 16:12:34 -070056#include <boot_stats.h>
Amir Samuelov57a6fa22013-06-05 16:36:43 +030057#include <sha.h>
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -070058#include <platform/iomap.h>
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -070059#include <boot_device.h>
Shashank Mittald3e54dd2014-08-28 15:24:02 -070060#include <boot_verifier.h>
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +053061#include <image_verify.h>
Matthew Qinbb7923d2015-02-09 10:56:09 +080062#include <decompress.h>
Unnati Gandhi17b3bfc2015-05-11 12:58:16 +053063#include <platform/timer.h>
lijuang511a2b52015-08-14 20:50:51 +080064#include <sys/types.h>
Channagoud Kadabi036c6052015-02-09 15:19:59 -080065#if USE_RPMB_FOR_DEVINFO
66#include <rpmb.h>
67#endif
Dima Zavin214cc642009-01-26 11:16:21 -080068
Channagoud Kadabi90869ce2015-04-27 11:15:14 -070069#if ENABLE_WBC
70#include <pm_app_smbchg.h>
71#endif
72
Neeti Desai17379b82012-06-04 18:42:53 -070073#if DEVICE_TREE
74#include <libfdt.h>
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070075#include <dev_tree.h>
Neeti Desai17379b82012-06-04 18:42:53 -070076#endif
77
Aparna Mallavarapu118ccae2015-06-03 13:47:11 +053078#if WDOG_SUPPORT
79#include <wdog.h>
80#endif
81
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -070082#include <reboot.h>
Shashank Mittalcd98d472011-08-02 14:29:24 -070083#include "image_verify.h"
Shashank Mittal024c0332010-02-03 11:44:00 -080084#include "recovery.h"
Brian Swetland9c4c0752009-01-25 16:23:50 -080085#include "bootimg.h"
86#include "fastboot.h"
Ajay Dudani5c761132011-04-07 20:19:04 -070087#include "sparse_format.h"
Ajay Dudanide984792015-03-02 09:57:41 -080088#include "meta_format.h"
Greg Grisco6e754772011-06-23 12:19:39 -070089#include "mmc.h"
Shashank Mittal162244e2011-08-08 19:01:25 -070090#include "devinfo.h"
Neeti Desai465491e2012-07-31 12:53:35 -070091#include "board.h"
Shashank Mittal162244e2011-08-08 19:01:25 -070092#include "scm.h"
Amit Blay6281ebc2015-01-11 14:44:08 +020093#include "mdtp.h"
Sridhar Parasuram32b30662015-07-10 13:33:22 -070094#include "secapp_loader.h"
lijuanga40d6302015-07-20 20:10:13 +080095#include <menu_keys_detect.h>
96#include <display_menu.h>
Channagoud Kadabi736c4962015-08-21 11:56:52 -070097#include "fastboot_test.h"
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -070098
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070099extern bool target_use_signed_kernel(void);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700100extern void platform_uninit(void);
Channagoud Kadabi33defe22013-06-18 18:35:40 -0700101extern void target_uninit(void);
Joonwoo Park61112782013-10-02 19:50:39 -0700102extern int get_target_boot_params(const char *cmdline, const char *part,
vijay kumar870515d2015-08-31 16:37:24 +0530103 char **buf);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700104
Sridhar Parasuram7e16d172015-07-05 11:35:23 -0700105void *info_buf;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700106void write_device_info_mmc(device_info *dev);
107void write_device_info_flash(device_info *dev);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -0700108static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size);
Channagoud Kadabiad259832015-05-29 11:14:17 -0700109static int aboot_frp_unlock(char *pname, void *data, unsigned sz);
Kishor PK38ed93d2017-04-25 14:19:26 +0530110static inline uint64_t validate_partition_size();
Parth Dixit54ac3bb2017-03-07 15:52:48 +0530111bool pwr_key_is_pressed = false;
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530112static bool is_systemd_present=false;
Mayank Grover351a75e2017-05-30 20:06:08 +0530113static void publish_getvar_multislot_vars();
Sridhar Parasurame94e8152014-10-24 14:06:03 -0700114/* fastboot command function pointer */
115typedef void (*fastboot_cmd_fn) (const char *, void *, unsigned);
Monika Singh292b3e92018-03-17 22:40:23 +0530116bool get_perm_attr_status();
Sridhar Parasurame94e8152014-10-24 14:06:03 -0700117
118struct fastboot_cmd_desc {
119 char * name;
120 fastboot_cmd_fn cb;
121};
122
Subbaraman Narayanamurthyeb92bcc2010-07-20 14:32:46 -0700123#define EXPAND(NAME) #NAME
124#define TARGET(NAME) EXPAND(NAME)
Brian Swetland2defe162009-08-18 14:35:59 -0700125
Ajay Singh Parmara7865a82015-04-16 21:27:52 -0700126#define DISPLAY_PANEL_HDMI "hdmi"
127
Ajay Dudanicd01f9b2010-02-23 21:13:04 -0800128#ifdef MEMBASE
129#define EMMC_BOOT_IMG_HEADER_ADDR (0xFF000+(MEMBASE))
130#else
David Ng183a7422009-12-07 14:55:21 -0800131#define EMMC_BOOT_IMG_HEADER_ADDR 0xFF000
Ajay Dudanicd01f9b2010-02-23 21:13:04 -0800132#endif
133
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700134#ifndef MEMSIZE
135#define MEMSIZE 1024*1024
136#endif
137
138#define MAX_TAGS_SIZE 1024
Kishor PKee5c0a32018-03-06 16:49:46 +0530139#define PLL_CODES_OFFSET 4096
Kun Liang2f1601a2013-08-12 16:29:54 +0800140/* make 4096 as default size to ensure EFS,EXT4's erasing */
141#define DEFAULT_ERASE_SIZE 4096
Ujwal Patelc0b0a252015-08-16 14:05:35 -0700142#define MAX_PANEL_BUF_SIZE 196
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +0530143#define FOOTER_SIZE 16384
Kun Liang2f1601a2013-08-12 16:29:54 +0800144
Dhaval Patelf83d73b2014-06-23 16:24:37 -0700145#define DISPLAY_DEFAULT_PREFIX "mdss_mdp"
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700146#define BOOT_DEV_MAX_LEN 64
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -0800147
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800148#define IS_ARM64(ptr) (ptr->magic_64 == KERNEL64_HDR_MAGIC) ? true : false
149
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -0700150#define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
151
Ameya Thakur10a33452016-06-13 14:24:26 -0700152//Size of the header that is used in case the boot image has
153//a uncompressed kernel + appended dtb
154#define PATCHED_KERNEL_HEADER_SIZE 20
155
156//String used to determine if the boot image has
157//a uncompressed kernel + appended dtb
158#define PATCHED_KERNEL_MAGIC "UNCOMPRESSED_IMG"
159
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800160#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700161static const char *emmc_cmdline = " androidboot.bootdevice=";
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700162#else
David Ng183a7422009-12-07 14:55:21 -0800163static const char *emmc_cmdline = " androidboot.emmc=true";
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700164#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530165static const char *dynamic_bootdev_cmdline =
166 " androidboot.boot_devices=soc/";
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800167static const char *usb_sn_cmdline = " androidboot.serialno=";
Pavel Nedev328ac822013-04-05 15:25:11 +0300168static const char *androidboot_mode = " androidboot.mode=";
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530169
170static const char *systemd_ffbm_mode = " systemd.unit=ffbm.target";
Matthew Qind886f3c2014-01-17 16:52:01 +0800171static const char *alarmboot_cmdline = " androidboot.alarmboot=true";
Pavel Nedev898298c2013-02-27 12:36:09 -0800172static const char *loglevel = " quiet";
Ajay Dudanica3a33c2011-11-18 08:31:40 -0800173static const char *battchg_pause = " androidboot.mode=charger";
Shashank Mittalcd98d472011-08-02 14:29:24 -0700174static const char *auth_kernel = " androidboot.authorized_kernel=true";
Pavel Nedev5614d222013-06-17 18:01:02 +0300175static const char *secondary_gpt_enable = " gpt";
Monika Singh292b3e92018-03-17 22:40:23 +0530176#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200177static const char *mdtp_activated_flag = " mdtp";
Monika Singh292b3e92018-03-17 22:40:23 +0530178#endif
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800179static const char *baseband_apq = " androidboot.baseband=apq";
180static const char *baseband_msm = " androidboot.baseband=msm";
181static const char *baseband_csfb = " androidboot.baseband=csfb";
182static const char *baseband_svlte2a = " androidboot.baseband=svlte2a";
Ajay Dudani403bc492011-09-30 16:17:21 -0700183static const char *baseband_mdm = " androidboot.baseband=mdm";
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800184static const char *baseband_mdm2 = " androidboot.baseband=mdm2";
Amol Jadi5c61a952012-05-04 17:05:35 -0700185static const char *baseband_sglte = " androidboot.baseband=sglte";
Amol Jadi2a15a272013-01-22 12:03:36 -0800186static const char *baseband_dsda = " androidboot.baseband=dsda";
187static const char *baseband_dsda2 = " androidboot.baseband=dsda2";
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800188static const char *baseband_sglte2 = " androidboot.baseband=sglte2";
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800189static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1";
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530190static const char *baseband_apq_nowgr = " androidboot.baseband=baseband_apq_nowgr";
Mayank Grover351a75e2017-05-30 20:06:08 +0530191static const char *androidboot_slot_suffix = " androidboot.slot_suffix=";
192static const char *skip_ramfs = " skip_initramfs";
Mayank Grover466d6562018-05-10 14:52:20 +0530193
194#if HIBERNATION_SUPPORT
195static const char *resume = " resume=/dev/mmcblk0p";
196#endif
197
Sourabh Banerjee6c7153c2018-03-20 01:21:57 +0530198#ifdef INIT_BIN_LE
199static const char *sys_path_cmdline = " rootwait ro init="INIT_BIN_LE;
200#else
Mayank Grover3804be72017-06-22 11:59:23 +0530201static const char *sys_path_cmdline = " rootwait ro init=/init";
Sourabh Banerjee6c7153c2018-03-20 01:21:57 +0530202#endif
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530203
204#if VERITY_LE
205static const char *verity_dev = " root=/dev/dm-0";
206static const char *verity_system_part = " dm=\"system";
207static const char *verity_params = " none ro,0 1 android-verity /dev/mmcblk0p";
208#else
Mayank Grover5384ed82018-05-09 12:09:24 +0530209static const char *sys_path = " root=/dev/mmcblk0p";
lijuang83ef4b22018-08-23 11:01:55 +0800210
211#define MAX_DTBO_IDX_STR 64
212static const char *android_boot_dtbo_idx = " androidboot.dtbo_idx=";
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530213#endif
Ajay Dudanid04110c2011-01-17 23:55:07 -0800214
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700215#if VERIFIED_BOOT
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700216static const char *verity_mode = " androidboot.veritymode=";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700217static const char *verified_state= " androidboot.verifiedbootstate=";
Parth Dixita5715a02015-10-29 12:25:10 +0530218static const char *keymaster_v1= " androidboot.keymaster=1";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700219//indexed based on enum values, green is 0 by default
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700220
221struct verified_boot_verity_mode vbvm[] =
222{
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700223#if ENABLE_VB_ATTEST
224 {false, "eio"},
225#else
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700226 {false, "logging"},
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700227#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700228 {true, "enforcing"},
229};
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700230struct verified_boot_state_name vbsn[] =
231{
232 {GREEN, "green"},
233 {ORANGE, "orange"},
234 {YELLOW,"yellow"},
235 {RED,"red" },
236};
237#endif
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700238/*As per spec delay wait time before shutdown in Red state*/
239#define DELAY_WAIT 30000
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700240static unsigned page_size = 0;
241static unsigned page_mask = 0;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +0530242static unsigned mmc_blocksize = 0;
243static unsigned mmc_blocksize_mask = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700244static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
245static bool boot_into_ffbm;
vijay kumar870515d2015-08-31 16:37:24 +0530246static char *target_boot_params = NULL;
Matthew Qind886f3c2014-01-17 16:52:01 +0800247static bool boot_reason_alarm;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -0700248static bool devinfo_present = true;
Channagoud Kadabi736c4962015-08-21 11:56:52 -0700249bool boot_into_fastboot = false;
Parth Dixit4097b622016-03-15 14:42:27 +0530250static uint32_t dt_size = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530251static char *vbcmdline;
252static bootinfo info = {0};
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530253static void *recovery_dtbo_buf = NULL;
254static uint32_t recovery_dtbo_size = 0;
255
Shashank Mittalcd98d472011-08-02 14:29:24 -0700256/* Assuming unauthorized kernel image by default */
257static int auth_kernel_img = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530258static device_info device = {DEVICE_MAGIC,0,0,0,0,{0},{0},{0},1,{0},0,{0}};
259
vijay kumarc65876c2015-04-24 13:29:16 +0530260static bool is_allow_unlock = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -0700261
vijay kumarca2e6812015-07-08 20:28:25 +0530262static char frp_ptns[2][8] = {"config","frp"};
263
lijuang511a2b52015-08-14 20:50:51 +0800264static const char *critical_flash_allowed_ptn[] = {
265 "aboot",
266 "rpm",
267 "tz",
268 "sbl",
269 "sdi",
270 "sbl1",
271 "xbl",
272 "hyp",
273 "pmic",
274 "bootloader",
275 "devinfo",
276 "partition"};
277
Dima Zavin42168f22009-01-30 11:52:22 -0800278struct atag_ptbl_entry
279{
280 char name[16];
281 unsigned offset;
282 unsigned size;
283 unsigned flags;
284};
285
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700286/*
287 * Partition info, required to be published
288 * for fastboot
289 */
290struct getvar_partition_info {
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530291 char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700292 char getvar_size[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for size */
293 char getvar_type[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for type */
294 char size_response[MAX_RSP_SIZE]; /* fastboot response for size */
295 char type_response[MAX_RSP_SIZE]; /* fastboot response for type */
296};
297
298/*
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530299 * Update the part_type_known for known paritions types.
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700300 */
Mayank Groverd38fe012018-03-13 15:33:16 +0530301#define RAW_STR "raw"
Mayank Grover52cd10a2018-03-15 12:57:54 +0530302#define EXT_STR "ext4"
303#define F2FS_STR "f2fs"
304
305#define FS_SUPERBLOCK_OFFSET 0x400
306#define EXT_MAGIC 0xEF53
307#define EXT_MAGIC_OFFSET_SB 0x38
308#define F2FS_MAGIC 0xF2F52010 // F2FS Magic Number
309#define F2FS_MAGIC_OFFSET_SB 0x0
310
311typedef enum fs_signature_type {
312 EXT_FS_SIGNATURE = 1,
313 EXT_F2FS_SIGNATURE = 2,
314 NO_FS = -1
315} fs_signature_type;
316
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530317struct getvar_partition_info part_info[NUM_PARTITIONS];
318struct getvar_partition_info part_type_known[] =
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700319{
Mayank Grover49920212018-02-09 18:15:55 +0530320 { "system" , "partition-size:", "partition-type:", "", "ext4" },
321 { "userdata" , "partition-size:", "partition-type:", "", "ext4" },
322 { "cache" , "partition-size:", "partition-type:", "", "ext4" },
323 { "recoveryfs" , "partition-size:", "partition-type:", "", "ext4" },
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700324};
325
326char max_download_size[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -0700327char charger_screen_enabled[MAX_RSP_SIZE];
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800328char sn_buf[13];
Dhaval Patel223ec952013-07-18 14:49:44 -0700329char display_panel_buf[MAX_PANEL_BUF_SIZE];
Unnati Gandhi62c8ab82014-01-24 11:01:01 +0530330char panel_display_mode[MAX_RSP_SIZE];
Mayank Grovera64dfbe2018-05-17 14:06:34 +0530331char soc_version_str[MAX_RSP_SIZE];
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530332char block_size_string[MAX_RSP_SIZE];
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +0530333#if PRODUCT_IOT
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530334
335/* For IOT we are using custom version */
336#define PRODUCT_IOT_VERSION "IOT001"
337char bootloader_version_string[MAX_RSP_SIZE];
338#endif
lijuang102dfa92015-10-09 18:31:03 +0800339
340#if CHECK_BAT_VOLTAGE
lijuang65c5a822015-08-29 16:35:36 +0800341char battery_voltage[MAX_RSP_SIZE];
lijuang102dfa92015-10-09 18:31:03 +0800342char battery_soc_ok [MAX_RSP_SIZE];
343#endif
344
lijuangf16461c2015-08-03 17:09:34 +0800345char get_variant[MAX_RSP_SIZE];
Greg Griscod6250552011-06-29 14:40:23 -0700346
Greg Griscod2471ef2011-07-14 13:00:42 -0700347extern int emmc_recovery_init(void);
348
Kinson Chik0b1c8162011-08-31 16:31:57 -0700349#if NO_KEYPAD_DRIVER
350extern int fastboot_trigger(void);
351#endif
Greg Griscod2471ef2011-07-14 13:00:42 -0700352
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530353static void update_ker_tags_rdisk_addr(boot_img_hdr *hdr, bool is_arm64)
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700354{
355 /* overwrite the destination of specified for the project */
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700356#ifdef ABOOT_IGNORE_BOOT_HEADER_ADDRS
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800357 if (is_arm64)
358 hdr->kernel_addr = ABOOT_FORCE_KERNEL64_ADDR;
359 else
360 hdr->kernel_addr = ABOOT_FORCE_KERNEL_ADDR;
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700361 hdr->ramdisk_addr = ABOOT_FORCE_RAMDISK_ADDR;
362 hdr->tags_addr = ABOOT_FORCE_TAGS_ADDR;
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700363#endif
364}
365
Dima Zavin42168f22009-01-30 11:52:22 -0800366static void ptentry_to_tag(unsigned **ptr, struct ptentry *ptn)
367{
368 struct atag_ptbl_entry atag_ptn;
369
370 memcpy(atag_ptn.name, ptn->name, 16);
371 atag_ptn.name[15] = '\0';
372 atag_ptn.offset = ptn->start;
373 atag_ptn.size = ptn->length;
374 atag_ptn.flags = ptn->flags;
375 memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry));
376 *ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned);
377}
Mayank Grover9df84c02018-08-30 15:46:35 +0530378#ifdef VERIFIED_BOOT_2
379void load_vbmeta_image(void **vbmeta_image_buf, uint32_t *vbmeta_image_sz)
380{
381 int index = 0;
382 char *vbm_img_buf = NULL;
383 unsigned long long ptn = 0;
384 unsigned long long ptn_size = 0;
385
386 /* Immediately return if dtbo is not supported */
387 index = partition_get_index("vbmeta");
388 ptn = partition_get_offset(index);
389 if(!ptn)
390 {
391 dprintf(CRITICAL, "ERROR: vbmeta partition not found.\n");
392 return;
393 }
394
395 ptn_size = partition_get_size(index);
396 if (ptn_size > MAX_SUPPORTED_VBMETA_IMG_BUF)
397 {
398 dprintf(CRITICAL, "ERROR: vbmeta parition size is greater than supported.\n");
399 return;
400 }
401
402 vbm_img_buf = (char *)memalign(CACHE_LINE, ROUNDUP((uint32_t)ptn_size, CACHE_LINE));
403 if (!vbm_img_buf)
404 {
405 dprintf(CRITICAL, "ERROR: vbmeta unable to locate buffer\n");
406 return;
407 }
408
409 mmc_set_lun(partition_get_lun(index));
410 if (mmc_read(ptn, (uint32_t *)vbm_img_buf, (uint32_t)ptn_size))
411 {
412 dprintf(CRITICAL, "ERROR: vbmeta read failure\n");
413 free(vbm_img_buf);
414 return;
415 }
416
417 *vbmeta_image_buf = vbm_img_buf;
418 *vbmeta_image_sz = (uint32_t)ptn_size;
419 return;
420}
421#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -0800422
lijuang102dfa92015-10-09 18:31:03 +0800423#if CHECK_BAT_VOLTAGE
424void update_battery_status(void)
425{
426 snprintf(battery_voltage,MAX_RSP_SIZE, "%d",target_get_battery_voltage());
427 snprintf(battery_soc_ok ,MAX_RSP_SIZE, "%s",target_battery_soc_ok()? "yes":"no");
428}
429#endif
430
Neeti Desaie245d492012-06-01 12:52:13 -0700431unsigned char *update_cmdline(const char * cmdline)
Brian Swetland9c4c0752009-01-25 16:23:50 -0800432{
David Ng183a7422009-12-07 14:55:21 -0800433 int cmdline_len = 0;
434 int have_cmdline = 0;
Amol Jadi168b7712012-03-06 16:15:00 -0800435 unsigned char *cmdline_final = NULL;
Neeti Desaie245d492012-06-01 12:52:13 -0700436 int pause_at_bootup = 0;
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800437 bool warm_boot = false;
Pavel Nedev5614d222013-06-17 18:01:02 +0300438 bool gpt_exists = partition_gpt_exists();
Joonwoo Park61112782013-10-02 19:50:39 -0700439 int have_target_boot_params = 0;
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700440 char *boot_dev_buf = NULL;
Monika Singh292b3e92018-03-17 22:40:23 +0530441#ifdef MDTP_SUPPORT
Mayank Grover351a75e2017-05-30 20:06:08 +0530442 bool is_mdtp_activated = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530443#endif
Mayank Grover351a75e2017-05-30 20:06:08 +0530444 int current_active_slot = INVALID;
Mayank Grover3804be72017-06-22 11:59:23 +0530445 int system_ptn_index = -1;
446 unsigned int lun = 0;
447 char lun_char_base = 'a';
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530448#if VERITY_LE
449 int syspath_buflen = strlen(verity_dev)
450 + strlen(verity_system_part) + (sizeof(char) * 2) + 2
451 + strlen(verity_params) + sizeof(int) + 2;
452#else
lijuang83ef4b22018-08-23 11:01:55 +0800453 int syspath_buflen = strlen(sys_path) + sizeof(int) + 2; /*allocate buflen for largest possible string*/
454 char dtbo_idx_str[MAX_DTBO_IDX_STR] = "\0";
455 int dtbo_idx = INVALID_PTN;
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530456#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530457 char syspath_buf[syspath_buflen];
Mayank Grover466d6562018-05-10 14:52:20 +0530458#if HIBERNATION_SUPPORT
459 int resume_buflen = strlen(resume) + sizeof(int) + 2;
460 char resume_buf[resume_buflen];
461 int swap_ptn_index = INVALID_PTN;
462#endif
463
Mayank Grover889be1b2017-09-12 20:12:23 +0530464#if VERIFIED_BOOT
465 uint32_t boot_state = RED;
466#endif
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530467
468#if USE_LE_SYSTEMD
469 is_systemd_present=true;
470#endif
471
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700472#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530473 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +0530474 {
475 boot_state = boot_verify_get_state();
476 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530477#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700478
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200479#ifdef MDTP_SUPPORT
480 mdtp_activated(&is_mdtp_activated);
481#endif /* MDTP_SUPPORT */
Dima Zavin42168f22009-01-30 11:52:22 -0800482
Brian Swetland9c4c0752009-01-25 16:23:50 -0800483 if (cmdline && cmdline[0]) {
David Ng183a7422009-12-07 14:55:21 -0800484 cmdline_len = strlen(cmdline);
485 have_cmdline = 1;
486 }
487 if (target_is_emmc_boot()) {
488 cmdline_len += strlen(emmc_cmdline);
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700489 boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN);
Mayank Groverb716edf2019-05-08 16:06:55 +0530490 if (!boot_dev_buf) {
491 dprintf(CRITICAL, "ERROR: Failed to allocate boot_dev_buf\n");
492 } else {
493 platform_boot_dev_cmdline(boot_dev_buf);
494#if USE_BOOTDEV_CMDLINE
495 cmdline_len += strlen(boot_dev_buf);
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700496#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530497 if (target_dynamic_partition_supported()) {
498 cmdline_len += strlen(dynamic_bootdev_cmdline);
499 cmdline_len += strlen(boot_dev_buf);
500 }
501 }
David Ng183a7422009-12-07 14:55:21 -0800502 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800503
504 cmdline_len += strlen(usb_sn_cmdline);
505 cmdline_len += strlen(sn_buf);
506
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700507#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530508 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700509 {
Mayank Grover889be1b2017-09-12 20:12:23 +0530510 cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
511 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
512 {
513 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
514 ASSERT(0);
515 }
516 cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
517 cmdline_len += strlen(keymaster_v1);
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700518 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530519#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700520
Monika Singh292b3e92018-03-17 22:40:23 +0530521
522 if (vbcmdline != NULL) {
523 dprintf(DEBUG, "UpdateCmdLine vbcmdline present len %d\n",
524 strlen(vbcmdline));
525 cmdline_len += strlen(vbcmdline);
526 }
527
Pavel Nedev5614d222013-06-17 18:01:02 +0300528 if (boot_into_recovery && gpt_exists)
529 cmdline_len += strlen(secondary_gpt_enable);
530
Monika Singh292b3e92018-03-17 22:40:23 +0530531#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200532 if(is_mdtp_activated)
533 cmdline_len += strlen(mdtp_activated_flag);
Monika Singh292b3e92018-03-17 22:40:23 +0530534#endif
Pavel Nedev328ac822013-04-05 15:25:11 +0300535 if (boot_into_ffbm) {
536 cmdline_len += strlen(androidboot_mode);
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530537
538 if(is_systemd_present)
539 cmdline_len += strlen(systemd_ffbm_mode);
540
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700541 cmdline_len += strlen(ffbm_mode_string);
Pavel Nedev898298c2013-02-27 12:36:09 -0800542 /* reduce kernel console messages to speed-up boot */
543 cmdline_len += strlen(loglevel);
Matthew Qind886f3c2014-01-17 16:52:01 +0800544 } else if (boot_reason_alarm) {
545 cmdline_len += strlen(alarmboot_cmdline);
Zhenhua Huang431dafa2015-06-30 16:13:37 +0800546 } else if ((target_build_variant_user() || device.charger_screen_enabled)
lijuang266b17d2018-08-17 18:53:42 +0800547 && target_pause_for_battery_charge() && !boot_into_recovery) {
David Ngf773dde2010-07-26 19:55:08 -0700548 pause_at_bootup = 1;
549 cmdline_len += strlen(battchg_pause);
550 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800551
Shashank Mittalcd98d472011-08-02 14:29:24 -0700552 if(target_use_signed_kernel() && auth_kernel_img) {
553 cmdline_len += strlen(auth_kernel);
554 }
555
Joonwoo Park61112782013-10-02 19:50:39 -0700556 if (get_target_boot_params(cmdline, boot_into_recovery ? "recoveryfs" :
557 "system",
vijay kumar870515d2015-08-31 16:37:24 +0530558 &target_boot_params) == 0) {
Joonwoo Park61112782013-10-02 19:50:39 -0700559 have_target_boot_params = 1;
560 cmdline_len += strlen(target_boot_params);
561 }
562
Ajay Dudanid04110c2011-01-17 23:55:07 -0800563 /* Determine correct androidboot.baseband to use */
564 switch(target_baseband())
565 {
566 case BASEBAND_APQ:
567 cmdline_len += strlen(baseband_apq);
568 break;
569
570 case BASEBAND_MSM:
571 cmdline_len += strlen(baseband_msm);
572 break;
573
574 case BASEBAND_CSFB:
575 cmdline_len += strlen(baseband_csfb);
576 break;
577
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800578 case BASEBAND_SVLTE2A:
579 cmdline_len += strlen(baseband_svlte2a);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800580 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700581
582 case BASEBAND_MDM:
583 cmdline_len += strlen(baseband_mdm);
584 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700585
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800586 case BASEBAND_MDM2:
587 cmdline_len += strlen(baseband_mdm2);
588 break;
589
Amol Jadi5c61a952012-05-04 17:05:35 -0700590 case BASEBAND_SGLTE:
591 cmdline_len += strlen(baseband_sglte);
592 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530593
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800594 case BASEBAND_SGLTE2:
595 cmdline_len += strlen(baseband_sglte2);
596 break;
597
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530598 case BASEBAND_DSDA:
599 cmdline_len += strlen(baseband_dsda);
600 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800601
602 case BASEBAND_DSDA2:
603 cmdline_len += strlen(baseband_dsda2);
604 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530605 case BASEBAND_APQ_NOWGR:
606 cmdline_len += strlen(baseband_apq_nowgr);
607 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800608 }
609
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300610#if ENABLE_DISPLAY
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800611 if (cmdline) {
612 if ((strstr(cmdline, DISPLAY_DEFAULT_PREFIX) == NULL) &&
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530613 target_display_panel_node(display_panel_buf,
614 MAX_PANEL_BUF_SIZE) &&
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800615 strlen(display_panel_buf)) {
616 cmdline_len += strlen(display_panel_buf);
617 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700618 }
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300619#endif
Dhaval Patel223ec952013-07-18 14:49:44 -0700620
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800621 if (target_warm_boot()) {
622 warm_boot = true;
623 cmdline_len += strlen(warmboot_cmdline);
624 }
625
Mayank Grover5384ed82018-05-09 12:09:24 +0530626 if (target_uses_system_as_root() ||
627 partition_multislot_is_supported())
Mayank Grover351a75e2017-05-30 20:06:08 +0530628 {
629 current_active_slot = partition_find_active_slot();
630 cmdline_len += (strlen(androidboot_slot_suffix)+
631 strlen(SUFFIX_SLOT(current_active_slot)));
632
Mayank Grover3804be72017-06-22 11:59:23 +0530633 system_ptn_index = partition_get_index("system");
634 if (platform_boot_dev_isemmc())
635 {
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530636#if VERITY_LE
637 /*
638 Condition 4: Verity and A/B both enabled
639 Eventual command line looks like:
640 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
641 ... root=/dev/dm-0 dm="system_<slot_suffix> none ro,0 1 android-verity /dev/mmcblk0p<NN>"
642 */
643 snprintf(syspath_buf, syspath_buflen, " %s %s%s %s%d\"",
644 verity_dev,
645 verity_system_part, suffix_slot[current_active_slot],
646 verity_params, system_ptn_index + 1);
647#else
648 /*
649 Condition 5: A/B enabled, but verity disabled
650 Eventual command line looks like:
651 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
652 ... root=/dev/mmcblk0p<NN> ...
653 */
654 snprintf(syspath_buf, syspath_buflen, " %s%d",
655 sys_path, system_ptn_index + 1);
656#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530657 }
658 else
659 {
660 lun = partition_get_lun(system_ptn_index);
661 snprintf(syspath_buf, syspath_buflen, " root=/dev/sd%c%d",
662 lun_char_base + lun,
663 partition_get_index_in_lun("system", lun));
664 }
Mayank Grover351a75e2017-05-30 20:06:08 +0530665
Monika Singh292b3e92018-03-17 22:40:23 +0530666#ifndef VERIFIED_BOOT_2
Mayank Grover3804be72017-06-22 11:59:23 +0530667 cmdline_len += strlen(syspath_buf);
Monika Singh292b3e92018-03-17 22:40:23 +0530668#endif
Mayank Grover5384ed82018-05-09 12:09:24 +0530669 }
670
671 if (target_uses_system_as_root() ||
672 partition_multislot_is_supported())
673 {
674 cmdline_len += strlen(sys_path_cmdline);
Mayank Groverb716edf2019-05-08 16:06:55 +0530675
676 /* For dynamic partition, support skip skip_initramfs */
677 if (!target_dynamic_partition_supported() &&
678 !boot_into_recovery)
Mayank Grover351a75e2017-05-30 20:06:08 +0530679 cmdline_len += strlen(skip_ramfs);
680 }
681
Mayank Grover466d6562018-05-10 14:52:20 +0530682#if HIBERNATION_SUPPORT
683 if (platform_boot_dev_isemmc())
684 {
685 swap_ptn_index = partition_get_index("swap");
686 if (swap_ptn_index != INVALID_PTN)
687 {
688 snprintf(resume_buf, resume_buflen,
689 " %s%d", resume,
690 (swap_ptn_index + 1));
691 cmdline_len += strlen(resume_buf);
692 }
693 else
694 {
695 dprintf(INFO, "WARNING: swap partition not found\n");
696 }
697 }
698#endif
699
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800700#if TARGET_CMDLINE_SUPPORT
701 char *target_cmdline_buf = malloc(TARGET_MAX_CMDLNBUF);
702 int target_cmd_line_len;
703 ASSERT(target_cmdline_buf);
704 target_cmd_line_len = target_update_cmdline(target_cmdline_buf);
705 cmdline_len += target_cmd_line_len;
706#endif
707
lijuang83ef4b22018-08-23 11:01:55 +0800708#if !VERITY_LE
709 dtbo_idx = get_dtbo_idx ();
710 if (dtbo_idx != INVALID_PTN) {
711 snprintf(dtbo_idx_str, sizeof(dtbo_idx_str), "%s%d",
712 android_boot_dtbo_idx, dtbo_idx);
713 cmdline_len += strlen (dtbo_idx_str);
714 }
715#endif
716
David Ng183a7422009-12-07 14:55:21 -0800717 if (cmdline_len > 0) {
718 const char *src;
Maria Yu52254c02014-07-04 16:14:54 +0800719 unsigned char *dst;
720
721 cmdline_final = (unsigned char*) malloc((cmdline_len + 4) & (~3));
722 ASSERT(cmdline_final != NULL);
vijay kumar287bb542015-09-29 13:01:52 +0530723 memset((void *)cmdline_final, 0, sizeof(*cmdline_final));
Maria Yu52254c02014-07-04 16:14:54 +0800724 dst = cmdline_final;
Neeti Desaie245d492012-06-01 12:52:13 -0700725
Amol Jadi168b7712012-03-06 16:15:00 -0800726 /* Save start ptr for debug print */
David Ng183a7422009-12-07 14:55:21 -0800727 if (have_cmdline) {
728 src = cmdline;
729 while ((*dst++ = *src++));
730 }
731 if (target_is_emmc_boot()) {
732 src = emmc_cmdline;
733 if (have_cmdline) --dst;
David Ngf773dde2010-07-26 19:55:08 -0700734 have_cmdline = 1;
735 while ((*dst++ = *src++));
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800736#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700737 src = boot_dev_buf;
Mayank Groverb716edf2019-05-08 16:06:55 +0530738 if (have_cmdline &&
739 boot_dev_buf) {
740 --dst;
741 while ((*dst++ = *src++));
742 }
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700743#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530744 /* Dynamic partition append boot_devices */
745 if (target_dynamic_partition_supported() &&
746 boot_dev_buf) {
747 src = dynamic_bootdev_cmdline;
748 if (have_cmdline) --dst;
749 while ((*dst++ = *src++));
750 src = boot_dev_buf;
751 if (have_cmdline) --dst;
752 while ((*dst++ = *src++));
753 }
David Ngf773dde2010-07-26 19:55:08 -0700754 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800755
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700756#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530757 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700758 {
Mayank Grover889be1b2017-09-12 20:12:23 +0530759 src = verified_state;
760 if(have_cmdline) --dst;
761 have_cmdline = 1;
762 while ((*dst++ = *src++));
763 src = vbsn[boot_state].name;
764 if(have_cmdline) --dst;
765 while ((*dst++ = *src++));
766
767 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
768 {
769 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
770 ASSERT(0);
771 }
772 src = verity_mode;
773 if(have_cmdline) --dst;
774 while ((*dst++ = *src++));
775 src = vbvm[device.verity_mode].name;
776 if(have_cmdline) -- dst;
777 while ((*dst++ = *src++));
778 src = keymaster_v1;
779 if(have_cmdline) --dst;
780 while ((*dst++ = *src++));
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700781 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530782#endif
Monika Singh292b3e92018-03-17 22:40:23 +0530783
784 if (vbcmdline != NULL) {
785 src = vbcmdline;
786 if (have_cmdline) --dst;
787 while ((*dst++ = *src++));
788 }
789
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800790 src = usb_sn_cmdline;
791 if (have_cmdline) --dst;
792 have_cmdline = 1;
793 while ((*dst++ = *src++));
794 src = sn_buf;
795 if (have_cmdline) --dst;
796 have_cmdline = 1;
797 while ((*dst++ = *src++));
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800798 if (warm_boot) {
799 if (have_cmdline) --dst;
800 src = warmboot_cmdline;
801 while ((*dst++ = *src++));
802 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800803
Pavel Nedev5614d222013-06-17 18:01:02 +0300804 if (boot_into_recovery && gpt_exists) {
805 src = secondary_gpt_enable;
806 if (have_cmdline) --dst;
807 while ((*dst++ = *src++));
808 }
Monika Singh292b3e92018-03-17 22:40:23 +0530809#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200810 if (is_mdtp_activated) {
811 src = mdtp_activated_flag;
812 if (have_cmdline) --dst;
813 while ((*dst++ = *src++));
814 }
Monika Singh292b3e92018-03-17 22:40:23 +0530815#endif
Pavel Nedev328ac822013-04-05 15:25:11 +0300816 if (boot_into_ffbm) {
817 src = androidboot_mode;
818 if (have_cmdline) --dst;
819 while ((*dst++ = *src++));
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700820 src = ffbm_mode_string;
Pavel Nedev328ac822013-04-05 15:25:11 +0300821 if (have_cmdline) --dst;
822 while ((*dst++ = *src++));
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530823
824 if(is_systemd_present) {
825 src = systemd_ffbm_mode;
826 if (have_cmdline) --dst;
827 while ((*dst++ = *src++));
828 }
829
Pavel Nedev898298c2013-02-27 12:36:09 -0800830 src = loglevel;
831 if (have_cmdline) --dst;
832 while ((*dst++ = *src++));
Matthew Qind886f3c2014-01-17 16:52:01 +0800833 } else if (boot_reason_alarm) {
834 src = alarmboot_cmdline;
835 if (have_cmdline) --dst;
836 while ((*dst++ = *src++));
Pavel Nedev328ac822013-04-05 15:25:11 +0300837 } else if (pause_at_bootup) {
David Ngf773dde2010-07-26 19:55:08 -0700838 src = battchg_pause;
839 if (have_cmdline) --dst;
David Ng183a7422009-12-07 14:55:21 -0800840 while ((*dst++ = *src++));
841 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800842
Shashank Mittalcd98d472011-08-02 14:29:24 -0700843 if(target_use_signed_kernel() && auth_kernel_img) {
844 src = auth_kernel;
845 if (have_cmdline) --dst;
846 while ((*dst++ = *src++));
847 }
848
Ajay Dudanid04110c2011-01-17 23:55:07 -0800849 switch(target_baseband())
850 {
851 case BASEBAND_APQ:
852 src = baseband_apq;
853 if (have_cmdline) --dst;
854 while ((*dst++ = *src++));
855 break;
856
857 case BASEBAND_MSM:
858 src = baseband_msm;
859 if (have_cmdline) --dst;
860 while ((*dst++ = *src++));
861 break;
862
863 case BASEBAND_CSFB:
864 src = baseband_csfb;
865 if (have_cmdline) --dst;
866 while ((*dst++ = *src++));
867 break;
868
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800869 case BASEBAND_SVLTE2A:
870 src = baseband_svlte2a;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800871 if (have_cmdline) --dst;
872 while ((*dst++ = *src++));
873 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700874
875 case BASEBAND_MDM:
876 src = baseband_mdm;
877 if (have_cmdline) --dst;
878 while ((*dst++ = *src++));
879 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700880
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800881 case BASEBAND_MDM2:
882 src = baseband_mdm2;
883 if (have_cmdline) --dst;
884 while ((*dst++ = *src++));
885 break;
886
Amol Jadi5c61a952012-05-04 17:05:35 -0700887 case BASEBAND_SGLTE:
888 src = baseband_sglte;
889 if (have_cmdline) --dst;
890 while ((*dst++ = *src++));
891 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530892
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800893 case BASEBAND_SGLTE2:
894 src = baseband_sglte2;
895 if (have_cmdline) --dst;
896 while ((*dst++ = *src++));
897 break;
898
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530899 case BASEBAND_DSDA:
900 src = baseband_dsda;
901 if (have_cmdline) --dst;
902 while ((*dst++ = *src++));
903 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800904
905 case BASEBAND_DSDA2:
906 src = baseband_dsda2;
907 if (have_cmdline) --dst;
908 while ((*dst++ = *src++));
909 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530910 case BASEBAND_APQ_NOWGR:
911 src = baseband_apq_nowgr;
912 if (have_cmdline) --dst;
913 while ((*dst++ = *src++));
914 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800915 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700916
917 if (strlen(display_panel_buf)) {
Dhaval Patel223ec952013-07-18 14:49:44 -0700918 src = display_panel_buf;
919 if (have_cmdline) --dst;
920 while ((*dst++ = *src++));
921 }
Joonwoo Park61112782013-10-02 19:50:39 -0700922
923 if (have_target_boot_params) {
924 if (have_cmdline) --dst;
925 src = target_boot_params;
926 while ((*dst++ = *src++));
vijay kumar870515d2015-08-31 16:37:24 +0530927 free(target_boot_params);
Joonwoo Park61112782013-10-02 19:50:39 -0700928 }
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800929
Mayank Grover351a75e2017-05-30 20:06:08 +0530930 if (partition_multislot_is_supported() && have_cmdline)
931 {
932 src = androidboot_slot_suffix;
933 --dst;
934 while ((*dst++ = *src++));
935 --dst;
936 src = SUFFIX_SLOT(current_active_slot);
937 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +0530938 }
Mayank Grover351a75e2017-05-30 20:06:08 +0530939
Mayank Grover351a75e2017-05-30 20:06:08 +0530940
Mayank Grover5384ed82018-05-09 12:09:24 +0530941 /*
942 * System-As-Root behaviour, system.img should contain both
943 * system content and ramdisk content, and should be mounted at
944 * root(a/b).
945 * Apending skip_ramfs for non a/b builds which use, system as root.
946 */
947 if ((target_uses_system_as_root() ||
948 partition_multislot_is_supported()) &&
949 have_cmdline)
950 {
Mayank Groverb716edf2019-05-08 16:06:55 +0530951 if (!target_dynamic_partition_supported() &&
952 !boot_into_recovery)
Mayank Grover5384ed82018-05-09 12:09:24 +0530953 {
954 src = skip_ramfs;
Mayank Grover351a75e2017-05-30 20:06:08 +0530955 --dst;
956 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +0530957 }
958
959 src = sys_path_cmdline;
960 --dst;
961 while ((*dst++ = *src++));
Mayank Grover3804be72017-06-22 11:59:23 +0530962
Monika Singh292b3e92018-03-17 22:40:23 +0530963#ifndef VERIFIED_BOOT_2
Mayank Grover5384ed82018-05-09 12:09:24 +0530964 src = syspath_buf;
965 --dst;
966 while ((*dst++ = *src++));
Monika Singh292b3e92018-03-17 22:40:23 +0530967#endif
Mayank Grover351a75e2017-05-30 20:06:08 +0530968 }
969
Mayank Grover466d6562018-05-10 14:52:20 +0530970#if HIBERNATION_SUPPORT
971 if (swap_ptn_index != INVALID_PTN)
972 {
973 src = resume_buf;
974 --dst;
975 while ((*dst++ = *src++));
976 }
977#endif
978
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800979#if TARGET_CMDLINE_SUPPORT
980 if (target_cmdline_buf && target_cmd_line_len)
981 {
982 if (have_cmdline) --dst;
983 src = target_cmdline_buf;
984 while((*dst++ = *src++));
985 free(target_cmdline_buf);
986 }
987#endif
lijuang83ef4b22018-08-23 11:01:55 +0800988
989#if !VERITY_LE
990 if (dtbo_idx != INVALID_PTN) {
991 src = dtbo_idx_str;
992 --dst;
993 while ((*dst++ = *src++));
994 }
995#endif
Neeti Desaie245d492012-06-01 12:52:13 -0700996 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700997
998
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700999 if (boot_dev_buf)
1000 free(boot_dev_buf);
1001
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08001002 if (cmdline_final)
1003 dprintf(INFO, "cmdline: %s\n", cmdline_final);
1004 else
1005 dprintf(INFO, "cmdline is NULL\n");
Neeti Desaie245d492012-06-01 12:52:13 -07001006 return cmdline_final;
1007}
1008
1009unsigned *atag_core(unsigned *ptr)
1010{
1011 /* CORE */
1012 *ptr++ = 2;
1013 *ptr++ = 0x54410001;
1014
1015 return ptr;
1016
1017}
1018
1019unsigned *atag_ramdisk(unsigned *ptr, void *ramdisk,
1020 unsigned ramdisk_size)
1021{
1022 if (ramdisk_size) {
1023 *ptr++ = 4;
1024 *ptr++ = 0x54420005;
1025 *ptr++ = (unsigned)ramdisk;
1026 *ptr++ = ramdisk_size;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001027 }
1028
Neeti Desaie245d492012-06-01 12:52:13 -07001029 return ptr;
1030}
1031
1032unsigned *atag_ptable(unsigned **ptr_addr)
1033{
1034 int i;
1035 struct ptable *ptable;
1036
1037 if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001038 *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
1039 sizeof(unsigned)));
Neeti Desaie245d492012-06-01 12:52:13 -07001040 *(*ptr_addr)++ = 0x4d534d70;
1041 for (i = 0; i < ptable->count; ++i)
1042 ptentry_to_tag(ptr_addr, ptable_get(ptable, i));
1043 }
1044
1045 return (*ptr_addr);
1046}
1047
1048unsigned *atag_cmdline(unsigned *ptr, const char *cmdline)
1049{
1050 int cmdline_length = 0;
1051 int n;
Neeti Desaie245d492012-06-01 12:52:13 -07001052 char *dest;
1053
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001054 cmdline_length = strlen((const char*)cmdline);
Neeti Desaie245d492012-06-01 12:52:13 -07001055 n = (cmdline_length + 4) & (~3);
1056
1057 *ptr++ = (n / 4) + 2;
1058 *ptr++ = 0x54410009;
1059 dest = (char *) ptr;
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001060 while ((*dest++ = *cmdline++));
Neeti Desaie245d492012-06-01 12:52:13 -07001061 ptr += (n / 4);
1062
1063 return ptr;
1064}
1065
1066unsigned *atag_end(unsigned *ptr)
1067{
Brian Swetland9c4c0752009-01-25 16:23:50 -08001068 /* END */
1069 *ptr++ = 0;
1070 *ptr++ = 0;
1071
Neeti Desaie245d492012-06-01 12:52:13 -07001072 return ptr;
1073}
1074
1075void generate_atags(unsigned *ptr, const char *cmdline,
1076 void *ramdisk, unsigned ramdisk_size)
1077{
vijay kumar21a37452015-12-29 16:23:21 +05301078 unsigned *orig_ptr = ptr;
Neeti Desaie245d492012-06-01 12:52:13 -07001079 ptr = atag_core(ptr);
1080 ptr = atag_ramdisk(ptr, ramdisk, ramdisk_size);
1081 ptr = target_atag_mem(ptr);
1082
1083 /* Skip NAND partition ATAGS for eMMC boot */
1084 if (!target_is_emmc_boot()){
1085 ptr = atag_ptable(&ptr);
1086 }
1087
vijay kumar21a37452015-12-29 16:23:21 +05301088 /*
1089 * Atags size filled till + cmdline size + 1 unsigned for 4-byte boundary + 4 unsigned
1090 * for atag identifier in atag_cmdline and atag_end should be with in MAX_TAGS_SIZE bytes
1091 */
Mayank Groverbc8a2ef2018-02-23 18:03:36 +05301092 if (!cmdline)
1093 return;
1094
vijay kumar21a37452015-12-29 16:23:21 +05301095 if (((ptr - orig_ptr) + strlen(cmdline) + 5 * sizeof(unsigned)) < MAX_TAGS_SIZE) {
1096 ptr = atag_cmdline(ptr, cmdline);
1097 ptr = atag_end(ptr);
1098 }
1099 else {
1100 dprintf(CRITICAL,"Crossing ATAGs Max size allowed\n");
1101 ASSERT(0);
1102 }
Neeti Desaie245d492012-06-01 12:52:13 -07001103}
1104
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001105typedef void entry_func_ptr(unsigned, unsigned, unsigned*);
Neeti Desaie245d492012-06-01 12:52:13 -07001106void boot_linux(void *kernel, unsigned *tags,
1107 const char *cmdline, unsigned machtype,
1108 void *ramdisk, unsigned ramdisk_size)
1109{
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001110 unsigned char *final_cmdline;
Amol Jadib6be5c12012-11-14 13:39:51 -08001111#if DEVICE_TREE
Neeti Desai17379b82012-06-04 18:42:53 -07001112 int ret = 0;
Amol Jadib6be5c12012-11-14 13:39:51 -08001113#endif
1114
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001115 void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001116 uint32_t tags_phys = PA((addr_t)tags);
vijay kumar1a50a642015-11-16 12:41:15 +05301117 struct kernel64_hdr *kptr = ((struct kernel64_hdr*)(PA((addr_t)kernel)));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001118
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301119 ramdisk = (void *)PA((addr_t)ramdisk);
Neeti Desaie245d492012-06-01 12:52:13 -07001120
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001121 final_cmdline = update_cmdline((const char*)cmdline);
1122
Neeti Desai17379b82012-06-04 18:42:53 -07001123#if DEVICE_TREE
Amol Jadib6be5c12012-11-14 13:39:51 -08001124 dprintf(INFO, "Updating device tree: start\n");
1125
Neeti Desai17379b82012-06-04 18:42:53 -07001126 /* Update the Device Tree */
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301127 ret = update_device_tree((void *)tags,(const char *)final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001128 if(ret)
1129 {
1130 dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
1131 ASSERT(0);
1132 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001133 dprintf(INFO, "Updating device tree: done\n");
Neeti Desai17379b82012-06-04 18:42:53 -07001134#else
Neeti Desaie245d492012-06-01 12:52:13 -07001135 /* Generating the Atags */
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001136 generate_atags(tags, final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001137#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001138
Monika Singhb0db4b82018-09-26 12:18:02 +05301139#if VERIFIED_BOOT || VERIFIED_BOOT_2
1140 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05301141 {
1142 if (device.verity_mode == 0) {
lijuangbdd9bb42016-03-01 18:22:17 +08001143#if FBCON_DISPLAY_MSG
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001144#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05301145 display_bootverify_menu(DISPLAY_MENU_EIO);
1146 wait_for_users_action();
1147 if(!pwr_key_is_pressed)
1148 shutdown_device();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001149#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301150 display_bootverify_menu(DISPLAY_MENU_LOGGING);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001151#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301152 wait_for_users_action();
lijuangbdd9bb42016-03-01 18:22:17 +08001153#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301154 dprintf(CRITICAL,
1155 "The dm-verity is not started in enforcing mode.\nWait for 5 seconds before proceeding\n");
1156 mdelay(5000);
lijuangbdd9bb42016-03-01 18:22:17 +08001157#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301158 }
lijuangbdd9bb42016-03-01 18:22:17 +08001159 }
lijuangbdd9bb42016-03-01 18:22:17 +08001160#endif
1161
1162#if VERIFIED_BOOT
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001163 /* Write protect the device info */
Channagoud Kadabi3bd9d1e2015-05-05 16:18:20 -07001164 if (!boot_into_recovery && target_build_variant_user() && devinfo_present && mmc_write_protect("devinfo", 1))
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001165 {
1166 dprintf(INFO, "Failed to write protect dev info\n");
1167 ASSERT(0);
1168 }
1169#endif
1170
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001171 /* Turn off splash screen if enabled */
1172#if DISPLAY_SPLASH_SCREEN
1173 target_display_shutdown();
1174#endif
1175
Veera Sundaram Sankaran67ea0932015-09-25 10:09:30 -07001176 /* Perform target specific cleanup */
1177 target_uninit();
Monika Singh292b3e92018-03-17 22:40:23 +05301178 free_verified_boot_resource(&info);
1179 if (final_cmdline)
1180 free(final_cmdline);
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001181
Deepa Dinamani33734bc2013-03-06 12:16:06 -08001182 dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d), tags/device tree @ %p\n",
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301183 entry, ramdisk, ramdisk_size, (void *)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001184
1185 enter_critical_section();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001186
Amol Jadi4421e652011-06-16 15:00:48 -07001187 /* do any platform specific cleanup before kernel entry */
1188 platform_uninit();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001189
Brian Swetland9c4c0752009-01-25 16:23:50 -08001190 arch_disable_cache(UCACHE);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001191
Amol Jadi504f9fe2012-08-16 13:56:48 -07001192#if ARM_WITH_MMU
Brian Swetland9c4c0752009-01-25 16:23:50 -08001193 arch_disable_mmu();
Amol Jadi504f9fe2012-08-16 13:56:48 -07001194#endif
Amol Jadi492d5a52013-03-15 16:12:34 -07001195 bs_set_timestamp(BS_KERNEL_ENTRY);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001196
1197 if (IS_ARM64(kptr))
1198 /* Jump to a 64bit kernel */
1199 scm_elexec_call((paddr_t)kernel, tags_phys);
1200 else
1201 /* Jump to a 32bit kernel */
1202 entry(0, machtype, (unsigned*)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001203}
1204
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001205/* Function to check if the memory address range falls within the aboot
1206 * boundaries.
1207 * start: Start of the memory region
1208 * size: Size of the memory region
1209 */
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301210int check_aboot_addr_range_overlap(uintptr_t start, uint32_t size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001211{
1212 /* Check for boundary conditions. */
Sundarajan Srinivasance2a0ea2013-12-16 17:02:56 -08001213 if ((UINT_MAX - start) < size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001214 return -1;
1215
1216 /* Check for memory overlap. */
1217 if ((start < MEMBASE) && ((start + size) <= MEMBASE))
1218 return 0;
Channagoud Kadabi94143912013-10-15 12:53:52 -07001219 else if (start >= (MEMBASE + MEMSIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001220 return 0;
1221 else
1222 return -1;
1223}
1224
Mayank Grovere559cec2017-10-17 15:12:03 +05301225/* Function to check if the memory address range falls beyond ddr region.
1226 * start: Start of the memory region
1227 * size: Size of the memory region
1228 */
1229int check_ddr_addr_range_bound(uintptr_t start, uint32_t size)
1230{
1231 uintptr_t ddr_pa_start_addr = PA(get_ddr_start());
1232 uint64_t ddr_size = smem_get_ddr_size();
1233 uint64_t ddr_pa_end_addr = ddr_pa_start_addr + ddr_size;
1234 uintptr_t pa_start_addr = PA(start);
1235
1236 /* Check for boundary conditions. */
1237 if ((UINT_MAX - start) < size)
1238 return -1;
1239
1240 /* Check if memory range is beyond the ddr range. */
1241 if (pa_start_addr < ddr_pa_start_addr ||
1242 pa_start_addr >= (ddr_pa_end_addr) ||
1243 (pa_start_addr + size) > ddr_pa_end_addr)
1244 return -1;
1245 else
1246 return 0;
1247}
1248
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001249BUF_DMA_ALIGN(buf, BOOT_IMG_MAX_PAGE_SIZE); //Equal to max-supported pagesize
Dima Zavin214cc642009-01-26 11:16:21 -08001250
Mayank Groverdd080e82018-09-04 20:12:13 +05301251int getimage(void **image_buffer, uint32_t *imgsize,
1252 const char *imgname)
Monika Singh292b3e92018-03-17 22:40:23 +05301253{
Mayank Groverdd080e82018-09-04 20:12:13 +05301254 uint32_t loadedindex;
1255 if (image_buffer == NULL || imgsize == NULL ||
Monika Singh292b3e92018-03-17 22:40:23 +05301256 imgname == NULL) {
1257 dprintf(CRITICAL, "getimage: invalid parameters\n");
1258 return -1;
1259 }
Mayank Groverdd080e82018-09-04 20:12:13 +05301260 for (loadedindex = 0; loadedindex < info.num_loaded_images; loadedindex++) {
1261 if (!strncmp(info.images[loadedindex].name, imgname,
Monika Singh292b3e92018-03-17 22:40:23 +05301262 strlen(imgname))) {
Mayank Groverdd080e82018-09-04 20:12:13 +05301263 *image_buffer = info.images[loadedindex].image_buffer;
1264 *imgsize = info.images[loadedindex].imgsize;
Mayank Grover027a9412018-09-04 15:12:05 +05301265 dprintf(SPEW, "getimage(): Loaded image [%s|%d]\n",
1266 info.images[loadedindex].name,
1267 info.images[loadedindex].imgsize);
Monika Singh292b3e92018-03-17 22:40:23 +05301268 return 0;
1269 }
1270 }
1271 return -1;
1272}
1273
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001274static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size)
1275{
1276 int ret;
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001277
1278#if !VERIFIED_BOOT
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001279#if IMAGE_VERIF_ALGO_SHA1
1280 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
1281#else
1282 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
1283#endif
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001284#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001285
1286 /* Assume device is rooted at this time. */
1287 device.is_tampered = 1;
1288
1289 dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
1290
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001291#if VERIFIED_BOOT
Monika Singh7d2fc272018-03-16 17:16:01 +05301292 uint32_t bootstate;
1293 if(boot_into_recovery &&
Mayank Grover68fbf0d2017-10-24 14:13:39 +05301294 (!partition_multislot_is_supported()))
Monika Singh7d2fc272018-03-16 17:16:01 +05301295 {
1296 ret = boot_verify_image((unsigned char *)bootimg_addr,
1297 bootimg_size, "/recovery", &bootstate);
1298 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001299 else
Monika Singh7d2fc272018-03-16 17:16:01 +05301300 {
1301 ret = boot_verify_image((unsigned char *)bootimg_addr,
1302 bootimg_size, "/boot", &bootstate);
1303 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001304 boot_verify_print_state();
1305#else
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001306 ret = image_verify((unsigned char *)bootimg_addr,
1307 (unsigned char *)(bootimg_addr + bootimg_size),
1308 bootimg_size,
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001309 auth_algo);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001310#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001311 dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret);
1312
1313 if (ret)
1314 {
1315 /* Authorized kernel */
1316 device.is_tampered = 0;
Sundarajan Srinivasan3fb21f12013-09-16 18:36:15 -07001317 auth_kernel_img = 1;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001318 }
1319
Amit Blay4aa292f2015-04-28 21:55:59 +03001320#ifdef MDTP_SUPPORT
1321 {
1322 /* Verify MDTP lock.
1323 * For boot & recovery partitions, use aboot's verification result.
1324 */
1325 mdtp_ext_partition_verification_t ext_partition;
1326 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
1327 ext_partition.integrity_state = device.is_tampered ? MDTP_PARTITION_STATE_INVALID : MDTP_PARTITION_STATE_VALID;
1328 ext_partition.page_size = 0; /* Not needed since already validated */
1329 ext_partition.image_addr = 0; /* Not needed since already validated */
1330 ext_partition.image_size = 0; /* Not needed since already validated */
1331 ext_partition.sig_avail = FALSE; /* Not needed since already validated */
1332 mdtp_fwlock_verify_lock(&ext_partition);
1333 }
1334#endif /* MDTP_SUPPORT */
1335
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001336#if USE_PCOM_SECBOOT
1337 set_tamper_flag(device.is_tampered);
1338#endif
1339
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001340#if VERIFIED_BOOT
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001341 switch(boot_verify_get_state())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001342 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001343 case RED:
lijuanga40d6302015-07-20 20:10:13 +08001344#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001345 display_bootverify_menu(DISPLAY_MENU_RED);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001346#if ENABLE_VB_ATTEST
1347 mdelay(DELAY_WAIT);
1348 shutdown_device();
1349#else
lijuanga40d6302015-07-20 20:10:13 +08001350 wait_for_users_action();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001351#endif
lijuanga40d6302015-07-20 20:10:13 +08001352#else
1353 dprintf(CRITICAL,
1354 "Your device has failed verification and may not work properly.\nWait for 5 seconds before proceeding\n");
1355 mdelay(5000);
1356#endif
1357
1358 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001359 case YELLOW:
lijuanga40d6302015-07-20 20:10:13 +08001360#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001361 display_bootverify_menu(DISPLAY_MENU_YELLOW);
lijuanga40d6302015-07-20 20:10:13 +08001362 wait_for_users_action();
1363#else
1364 dprintf(CRITICAL,
1365 "Your device has loaded a different operating system.\nWait for 5 seconds before proceeding\n");
1366 mdelay(5000);
1367#endif
1368 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001369 default:
lijuanga40d6302015-07-20 20:10:13 +08001370 break;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001371 }
1372#endif
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001373#if !VERIFIED_BOOT
Unnati Gandhi1be04752015-03-27 19:41:53 +05301374 if(device.is_tampered)
1375 {
1376 write_device_info_mmc(&device);
1377 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05301378 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Unnati Gandhi1be04752015-03-27 19:41:53 +05301379 #endif
1380 #ifdef ASSERT_ON_TAMPER
1381 dprintf(CRITICAL, "Device is tampered. Asserting..\n");
1382 ASSERT(0);
1383 #endif
1384 }
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001385#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001386}
1387
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301388static bool check_format_bit()
1389{
1390 bool ret = false;
1391 int index;
1392 uint64_t offset;
1393 struct boot_selection_info *in = NULL;
1394 char *buf = NULL;
1395
1396 index = partition_get_index("bootselect");
1397 if (index == INVALID_PTN)
1398 {
1399 dprintf(INFO, "Unable to locate /bootselect partition\n");
1400 return ret;
1401 }
1402 offset = partition_get_offset(index);
1403 if(!offset)
1404 {
1405 dprintf(INFO, "partition /bootselect doesn't exist\n");
1406 return ret;
1407 }
1408 buf = (char *) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE));
Mayank Grover48860402016-11-29 12:34:53 +05301409 mmc_set_lun(partition_get_lun(index));
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301410 ASSERT(buf);
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301411 if (mmc_read(offset, (uint32_t *)buf, page_size))
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301412 {
1413 dprintf(INFO, "mmc read failure /bootselect %d\n", page_size);
1414 free(buf);
1415 return ret;
1416 }
1417 in = (struct boot_selection_info *) buf;
1418 if ((in->signature == BOOTSELECT_SIGNATURE) &&
1419 (in->version == BOOTSELECT_VERSION)) {
1420 if ((in->state_info & BOOTSELECT_FORMAT) &&
1421 !(in->state_info & BOOTSELECT_FACTORY))
1422 ret = true;
1423 } else {
1424 dprintf(CRITICAL, "Signature: 0x%08x or version: 0x%08x mismatched of /bootselect\n",
1425 in->signature, in->version);
1426 ASSERT(0);
1427 }
1428 free(buf);
1429 return ret;
1430}
1431
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001432void boot_verifier_init()
1433{
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001434 uint32_t boot_state;
1435 /* Check if device unlock */
1436 if(device.is_unlocked)
1437 {
1438 boot_verify_send_event(DEV_UNLOCK);
1439 boot_verify_print_state();
1440 dprintf(CRITICAL, "Device is unlocked! Skipping verification...\n");
1441 return;
1442 }
1443 else
1444 {
1445 boot_verify_send_event(BOOT_INIT);
1446 }
1447
1448 /* Initialize keystore */
1449 boot_state = boot_verify_keystore_init();
1450 if(boot_state == YELLOW)
1451 {
1452 boot_verify_print_state();
1453 dprintf(CRITICAL, "Keystore verification failed! Continuing anyways...\n");
1454 }
1455}
1456
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301457/* Function to return recovery appended dtbo buffer info */
1458void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf)
1459{
1460 *dtbo_size = recovery_dtbo_size;
1461 *dtbo_buf = recovery_dtbo_buf;
1462 return;
1463}
1464
Shashank Mittal23b8f422010-04-16 19:27:21 -07001465int boot_linux_from_mmc(void)
1466{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301467 boot_img_hdr *hdr = (void*) buf;
1468 boot_img_hdr *uhdr;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001469 unsigned offset = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001470 int rcode;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001471 unsigned long long ptn = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07001472 int index = INVALID_PTN;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001473
Shashank Mittalcd98d472011-08-02 14:29:24 -07001474 unsigned char *image_addr = 0;
1475 unsigned kernel_actual;
1476 unsigned ramdisk_actual;
1477 unsigned imagesize_actual;
Neeti Desai465491e2012-07-31 12:53:35 -07001478 unsigned second_actual = 0;
Neeti Desai465491e2012-07-31 12:53:35 -07001479
Matthew Qin271927e2015-03-31 22:07:07 -04001480 unsigned int dtb_size = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001481 unsigned int out_len = 0;
1482 unsigned int out_avai_len = 0;
1483 unsigned char *out_addr = NULL;
1484 uint32_t dtb_offset = 0;
1485 unsigned char *kernel_start_addr = NULL;
1486 unsigned int kernel_size = 0;
Ameya Thakur10a33452016-06-13 14:24:26 -07001487 unsigned int patched_kernel_hdr_size = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301488 uint64_t image_size = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001489 int rc;
Monika Singh292b3e92018-03-17 22:40:23 +05301490#if VERIFIED_BOOT_2
1491 int status;
Mayank Grover027a9412018-09-04 15:12:05 +05301492 void *dtbo_image_buf = NULL;
1493 uint32_t dtbo_image_sz = 0;
Mayank Grover9df84c02018-08-30 15:46:35 +05301494 void *vbmeta_image_buf = NULL;
1495 uint32_t vbmeta_image_sz = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05301496#endif
Mayank Groverc93cad82017-10-03 12:23:45 +05301497 char *ptn_name = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001498#if DEVICE_TREE
1499 struct dt_table *table;
Joel Kingaa335dc2013-06-03 16:11:08 -07001500 struct dt_entry dt_entry;
Neeti Desai465491e2012-07-31 12:53:35 -07001501 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001502 uint32_t dt_actual;
Deepa Dinamani19648b42013-09-05 17:05:55 -07001503 uint32_t dt_hdr_size;
Matthew Qin271927e2015-03-31 22:07:07 -04001504 unsigned char *best_match_dt_addr = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001505#endif
Matthew Qin49e51fa2015-02-09 10:40:45 +08001506 struct kernel64_hdr *kptr = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05301507 int current_active_slot = INVALID;
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001508
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301509 if (check_format_bit())
1510 boot_into_recovery = 1;
1511
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001512 if (!boot_into_recovery) {
1513 memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string));
1514 rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string));
1515 if (rcode <= 0) {
1516 boot_into_ffbm = false;
1517 if (rcode < 0)
1518 dprintf(CRITICAL,"failed to get ffbm cookie");
1519 } else
1520 boot_into_ffbm = true;
1521 } else
1522 boot_into_ffbm = false;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301523 uhdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001524 if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
1525 dprintf(INFO, "Unified boot method!\n");
1526 hdr = uhdr;
1527 goto unified_boot;
1528 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301529
1530 /* For a/b recovery image code is on boot partition.
1531 If we support multislot, always use boot partition. */
1532 if (boot_into_recovery &&
Mayank Grover8ab4a762019-04-25 17:23:34 +05301533 ((!partition_multislot_is_supported()) ||
1534 (target_dynamic_partition_supported())))
Mayank Groverc93cad82017-10-03 12:23:45 +05301535 ptn_name = "recovery";
1536 else
1537 ptn_name = "boot";
1538
1539 index = partition_get_index(ptn_name);
1540 ptn = partition_get_offset(index);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301541 image_size = partition_get_size(index);
1542 if(ptn == 0 || image_size == 0) {
Mayank Groverc93cad82017-10-03 12:23:45 +05301543 dprintf(CRITICAL, "ERROR: No %s partition found\n", ptn_name);
1544 return -1;
Kinson Chikf1a43512011-07-14 11:28:39 -07001545 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301546
Channagoud Kadabief0547c2015-02-10 12:57:38 -08001547 /* Set Lun for boot & recovery partitions */
1548 mmc_set_lun(partition_get_lun(index));
Shashank Mittal23b8f422010-04-16 19:27:21 -07001549
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301550 if (mmc_read(ptn + offset, (uint32_t *) buf, page_size)) {
Shashank Mittal23b8f422010-04-16 19:27:21 -07001551 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
1552 return -1;
1553 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07001554
1555 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07001556 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Mayank Grover351a75e2017-05-30 20:06:08 +05301557 return ERR_INVALID_BOOT_MAGIC;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001558 }
1559
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001560 if (hdr->page_size && (hdr->page_size != page_size)) {
vijay kumar2e21b3a2014-06-26 17:40:15 +05301561
1562 if (hdr->page_size > BOOT_IMG_MAX_PAGE_SIZE) {
1563 dprintf(CRITICAL, "ERROR: Invalid page size\n");
1564 return -1;
1565 }
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001566 page_size = hdr->page_size;
1567 page_mask = page_size - 1;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001568 }
1569
Matthew Qin49e51fa2015-02-09 10:40:45 +08001570 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1571 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301572 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001573
Matthew Qin49e51fa2015-02-09 10:40:45 +08001574 image_addr = (unsigned char *)target_get_scratch_address();
Mayank Grover6fd36792018-09-10 13:26:58 +05301575#if VERIFIED_BOOT_2
1576 /* Create hole in start of image for VB salt to copy */
1577 image_addr += SALT_BUFF_OFFSET;
1578#endif
Kishor PK9e91b592017-05-24 12:14:55 +05301579 memcpy(image_addr, (void *)buf, page_size);
1580
1581 /* ensure commandline is terminated */
1582 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001583
1584#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05301585#ifndef OSVERSION_IN_BOOTIMAGE
1586 dt_size = hdr->dt_size;
Mayank Grover5a502582018-09-12 11:24:49 +05301587#else
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301588 dprintf(INFO, "BootImage Header: %d\n", hdr->header_version);
Mayank Grover5a502582018-09-12 11:24:49 +05301589#endif
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301590
Parth Dixit4097b622016-03-15 14:42:27 +05301591 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301592 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 +05301593 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1594 return -1;
1595 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301596 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001597#else
Kishor PKd8ddcad2017-07-27 13:53:57 +05301598 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 +05301599 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1600 return -1;
1601 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301602 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001603#endif
1604
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301605#ifdef OSVERSION_IN_BOOTIMAGE
1606 /* If header version is ONE and booting into recovery,
1607 dtbo is appended with recovery image.
1608 Doing following:
1609 * Validating the recovery offset and size.
1610 * Extracting recovery dtbo to be used as dtbo.
1611 */
1612 if (boot_into_recovery &&
1613 hdr->header_version == BOOT_HEADER_VERSION_ONE)
1614 {
1615 struct boot_img_hdr_v1 *hdr1 =
1616 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
Mayank Grovera1a83c72018-09-24 11:23:15 +05301617 unsigned int recovery_dtbo_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301618
Mayank Grovera1a83c72018-09-24 11:23:15 +05301619 recovery_dtbo_actual = ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301620 if ((hdr1->header_size !=
1621 sizeof(struct boot_img_hdr_v1) + sizeof(boot_img_hdr)))
1622 {
1623 dprintf(CRITICAL, "Invalid boot image header: %d\n", hdr1->header_size);
1624 return -1;
1625 }
1626
Mayank Grovera1a83c72018-09-24 11:23:15 +05301627 if (recovery_dtbo_actual > MAX_SUPPORTED_DTBO_IMG_BUF)
1628 {
1629 dprintf(CRITICAL, "Recovery Dtbo Size too big %x, Allowed size %x\n", recovery_dtbo_actual,
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301630 MAX_SUPPORTED_DTBO_IMG_BUF);
1631 return -1;
1632 }
1633
Mayank Grovera1a83c72018-09-24 11:23:15 +05301634 if (UINT_MAX < ((uint64_t)imagesize_actual + recovery_dtbo_actual))
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301635 {
1636 dprintf(CRITICAL, "Integer overflow detected in recoveryimage header fields at %u in %s\n",__LINE__,__FILE__);
1637 return -1;
1638 }
1639
Mayank Grovera1a83c72018-09-24 11:23:15 +05301640 if (UINT_MAX < (hdr1->recovery_dtbo_offset + recovery_dtbo_actual)) {
1641 dprintf(CRITICAL,
1642 "Integer overflow detected in recovery image header fields at %u in %s\n",__LINE__,__FILE__);
1643 return -1;
1644 }
1645
1646 if (hdr1->recovery_dtbo_offset + recovery_dtbo_actual > image_size)
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301647 {
1648 dprintf(CRITICAL, "Invalid recovery dtbo: Recovery Dtbo Offset=0x%llx,"
1649 " Recovery Dtbo Size=0x%x, Image Size=0x%llx\n",
1650 hdr1->recovery_dtbo_offset, recovery_dtbo_size, image_size);
1651 return -1;
1652 }
1653
1654 recovery_dtbo_buf = (void *)(hdr1->recovery_dtbo_offset + image_addr);
Mayank Grovera1a83c72018-09-24 11:23:15 +05301655 recovery_dtbo_size = recovery_dtbo_actual;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301656 imagesize_actual += recovery_dtbo_size;
1657
1658 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
1659 dprintf(SPEW, "Recovery Dtbo Size 0x%x\n", recovery_dtbo_size);
1660 dprintf(SPEW, "Recovery Dtbo Offset 0x%llx\n", hdr1->recovery_dtbo_offset);
1661
1662 }
1663#endif
1664
Saranya Chidurab1aaf232018-11-19 15:47:50 +05301665 /* Validate the boot/recovery image size is within the bounds of partition size */
1666 if (imagesize_actual > image_size) {
1667 dprintf(CRITICAL, "Image size is greater than partition size.\n");
1668 return -1;
1669 }
1670
Matthew Qin49e51fa2015-02-09 10:40:45 +08001671#if VERIFIED_BOOT
1672 boot_verifier_init();
1673#endif
1674
Mayank Grover1ceaee22019-04-01 17:54:32 +05301675#if VERIFIED_BOOT_2
1676 /* read full partition if device is unlocked */
1677 if (device.is_unlocked)
1678 imagesize_actual = image_size;
1679#endif
1680
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301681 if (check_aboot_addr_range_overlap((uintptr_t) image_addr, imagesize_actual))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001682 {
1683 dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
1684 return -1;
1685 }
1686
Matthew Qinbb7923d2015-02-09 10:56:09 +08001687 /*
1688 * Update loading flow of bootimage to support compressed/uncompressed
1689 * bootimage on both 64bit and 32bit platform.
1690 * 1. Load bootimage from emmc partition onto DDR.
1691 * 2. Check if bootimage is gzip format. If yes, decompress compressed kernel
1692 * 3. Check kernel header and update kernel load addr for 64bit and 32bit
1693 * platform accordingly.
1694 * 4. Sanity Check on kernel_addr and ramdisk_addr and copy data.
1695 */
Mayank Grover351a75e2017-05-30 20:06:08 +05301696 if (partition_multislot_is_supported())
1697 {
1698 current_active_slot = partition_find_active_slot();
1699 dprintf(INFO, "Loading boot image (%d) active_slot(%s): start\n",
1700 imagesize_actual, SUFFIX_SLOT(current_active_slot));
1701 }
1702 else
1703 {
1704 dprintf(INFO, "Loading (%s) image (%d): start\n",
1705 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
1706 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001707 bs_set_timestamp(BS_KERNEL_LOAD_START);
1708
Gaurav Nebhwani43e2a462016-03-17 21:32:56 +05301709 if ((target_get_max_flash_size() - page_size) < imagesize_actual)
1710 {
1711 dprintf(CRITICAL, "booimage size is greater than DDR can hold\n");
1712 return -1;
1713 }
Kishor PK9e91b592017-05-24 12:14:55 +05301714 offset = page_size;
1715 /* Read image without signature and header*/
1716 if (mmc_read(ptn + offset, (void *)(image_addr + offset), imagesize_actual - page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001717 {
1718 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
1719 return -1;
1720 }
1721
Mayank Grover351a75e2017-05-30 20:06:08 +05301722 if (partition_multislot_is_supported())
1723 {
1724 dprintf(INFO, "Loading boot image (%d) active_slot(%s): done\n",
1725 imagesize_actual, SUFFIX_SLOT(current_active_slot));
1726 }
1727 else
1728 {
1729 dprintf(INFO, "Loading (%s) image (%d): done\n",
Channagoud Kadabif0705b52015-08-20 14:16:08 -07001730 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
1731
Mayank Grover351a75e2017-05-30 20:06:08 +05301732 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001733 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
1734
1735 /* Authenticate Kernel */
1736 dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
1737 (int) target_use_signed_kernel(),
1738 device.is_unlocked,
1739 device.is_tampered);
Monika Singh292b3e92018-03-17 22:40:23 +05301740#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05301741 /* if device is unlocked skip reading signature, as full partition is read */
1742 if (!device.is_unlocked)
Monika Singh292b3e92018-03-17 22:40:23 +05301743 {
Mayank Grover1ceaee22019-04-01 17:54:32 +05301744 offset = imagesize_actual;
1745 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
1746 {
1747 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
1748 return -1;
1749 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001750
Mayank Grover1ceaee22019-04-01 17:54:32 +05301751 /* Read signature */
1752 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
1753 {
1754 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
1755 return -1;
1756 }
Monika Singh292b3e92018-03-17 22:40:23 +05301757 }
1758
Mayank Grover027a9412018-09-04 15:12:05 +05301759 /* load and validate dtbo partition */
1760 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
1761
Mayank Grover9df84c02018-08-30 15:46:35 +05301762 /* load vbmeta partition */
1763 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
1764
Monika Singh292b3e92018-03-17 22:40:23 +05301765 memset(&info, 0, sizeof(bootinfo));
Mayank Grover027a9412018-09-04 15:12:05 +05301766
1767 /* Pass loaded boot image passed */
Mayank Grover6fd36792018-09-10 13:26:58 +05301768 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(image_addr);
Mayank Grover027a9412018-09-04 15:12:05 +05301769 info.images[IMG_BOOT].imgsize = imagesize_actual;
1770 info.images[IMG_BOOT].name = ptn_name;
1771 ++info.num_loaded_images;
1772
1773 /* Pass loaded dtbo image */
1774 if (dtbo_image_buf != NULL) {
Mayank Grover6fd36792018-09-10 13:26:58 +05301775 info.images[IMG_DTBO].image_buffer =
1776 SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
Mayank Grover027a9412018-09-04 15:12:05 +05301777 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
1778 info.images[IMG_DTBO].name = "dtbo";
1779 ++info.num_loaded_images;
1780 }
1781
Mayank Grover9df84c02018-08-30 15:46:35 +05301782 /* Pass loaded vbmeta image */
1783 if (vbmeta_image_buf != NULL) {
1784 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
1785 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
1786 info.images[IMG_VBMETA].name = "vbmeta";
1787 ++info.num_loaded_images;
1788 }
1789
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301790 info.header_version = hdr->header_version;
Monika Singh292b3e92018-03-17 22:40:23 +05301791 info.multi_slot_boot = partition_multislot_is_supported();
1792 info.bootreason_alarm = boot_reason_alarm;
1793 info.bootinto_recovery = boot_into_recovery;
1794 status = load_image_and_auth(&info);
1795 if(status)
1796 return -1;
1797
1798 vbcmdline = info.vbcmdline;
Mayank Grover9df84c02018-08-30 15:46:35 +05301799
1800 /* Free the buffer allocated to vbmeta post verification */
Saranya Chidurab4933332018-10-15 17:30:06 +05301801 if (vbmeta_image_buf != NULL) {
1802 free(vbmeta_image_buf);
1803 --info.num_loaded_images;
1804 }
Monika Singh292b3e92018-03-17 22:40:23 +05301805#else
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001806 /* Change the condition a little bit to include the test framework support.
1807 * We would never reach this point if device is in fastboot mode, even if we did
1808 * that means we are in test mode, so execute kernel authentication part for the
1809 * tests */
Parth Dixitcb0c6082015-12-30 15:01:13 +05301810 if((target_use_signed_kernel() && (!device.is_unlocked)) || is_test_mode_enabled())
Matthew Qin49e51fa2015-02-09 10:40:45 +08001811 {
1812 offset = imagesize_actual;
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301813 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001814 {
1815 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
1816 return -1;
1817 }
1818
1819 /* Read signature */
1820 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
1821 {
1822 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
1823 return -1;
1824 }
1825
1826 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001827 /* The purpose of our test is done here */
Parth Dixitcb0c6082015-12-30 15:01:13 +05301828 if(is_test_mode_enabled() && auth_kernel_img)
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001829 return 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001830 } else {
1831 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
1832 #ifdef TZ_SAVE_KERNEL_HASH
1833 aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
1834 #endif /* TZ_SAVE_KERNEL_HASH */
Amit Blay4aa292f2015-04-28 21:55:59 +03001835
1836#ifdef MDTP_SUPPORT
1837 {
1838 /* Verify MDTP lock.
1839 * For boot & recovery partitions, MDTP will use boot_verifier APIs,
1840 * since verification was skipped in aboot. The signature is not part of the loaded image.
1841 */
1842 mdtp_ext_partition_verification_t ext_partition;
1843 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
1844 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
1845 ext_partition.page_size = page_size;
1846 ext_partition.image_addr = (uint32)image_addr;
1847 ext_partition.image_size = imagesize_actual;
1848 ext_partition.sig_avail = FALSE;
1849 mdtp_fwlock_verify_lock(&ext_partition);
1850 }
1851#endif /* MDTP_SUPPORT */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001852 }
Monika Singh292b3e92018-03-17 22:40:23 +05301853#endif
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001854
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -07001855#if VERIFIED_BOOT
taozhang93088bd2016-11-16 15:50:46 +08001856 if((boot_verify_get_state() == ORANGE) && (!boot_into_ffbm))
Reut Zysmanba8a9d52016-02-18 11:44:04 +02001857 {
1858#if FBCON_DISPLAY_MSG
1859 display_bootverify_menu(DISPLAY_MENU_ORANGE);
1860 wait_for_users_action();
1861#else
1862 dprintf(CRITICAL,
1863 "Your device has been unlocked and can't be trusted.\nWait for 5 seconds before proceeding\n");
1864 mdelay(5000);
1865#endif
1866 }
1867#endif
1868
1869#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05301870 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05301871 {
1872 /* set boot and system versions. */
1873 set_os_version((unsigned char *)image_addr);
1874 // send root of trust
1875 if(!send_rot_command((uint32_t)device.is_unlocked))
1876 ASSERT(0);
1877 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05301878#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001879 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08001880 * Check if the kernel image is a gzip package. If yes, need to decompress it.
1881 * If not, continue booting.
1882 */
1883 if (is_gzip_package((unsigned char *)(image_addr + page_size), hdr->kernel_size))
1884 {
1885 out_addr = (unsigned char *)(image_addr + imagesize_actual + page_size);
1886 out_avai_len = target_get_max_flash_size() - imagesize_actual - page_size;
Mayank Grover027a9412018-09-04 15:12:05 +05301887#if VERIFIED_BOOT_2
1888 if (dtbo_image_sz)
1889 out_avai_len -= DTBO_IMG_BUF;
1890#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04001891 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001892 rc = decompress((unsigned char *)(image_addr + page_size),
1893 hdr->kernel_size, out_addr, out_avai_len,
1894 &dtb_offset, &out_len);
1895 if (rc)
1896 {
Matthew Qin0b15b322015-05-19 05:20:54 -04001897 dprintf(CRITICAL, "decompressing kernel image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001898 ASSERT(0);
1899 }
1900
Matthew Qin0b15b322015-05-19 05:20:54 -04001901 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001902 kptr = (struct kernel64_hdr *)out_addr;
1903 kernel_start_addr = out_addr;
1904 kernel_size = out_len;
1905 } else {
Ameya Thakur10a33452016-06-13 14:24:26 -07001906 dprintf(INFO, "Uncpmpressed kernel in use\n");
1907 if (!strncmp((char*)(image_addr + page_size),
1908 PATCHED_KERNEL_MAGIC,
1909 sizeof(PATCHED_KERNEL_MAGIC) - 1)) {
1910 dprintf(INFO, "Patched kernel detected\n");
1911 kptr = (struct kernel64_hdr *)(image_addr + page_size +
1912 PATCHED_KERNEL_HEADER_SIZE);
1913 //The size of the kernel is stored at start of kernel image + 16
1914 //The dtb would start just after the kernel
1915 dtb_offset = *((uint32_t*)((unsigned char*)
1916 (image_addr + page_size +
1917 sizeof(PATCHED_KERNEL_MAGIC) -
1918 1)));
1919 //The actual kernel starts after the 20 byte header.
1920 kernel_start_addr = (unsigned char*)(image_addr +
1921 page_size + PATCHED_KERNEL_HEADER_SIZE);
1922 kernel_size = hdr->kernel_size;
1923 patched_kernel_hdr_size = PATCHED_KERNEL_HEADER_SIZE;
1924 } else {
1925 dprintf(INFO, "Kernel image not patched..Unable to locate dt offset\n");
1926 kptr = (struct kernel64_hdr *)(image_addr + page_size);
1927 kernel_start_addr = (unsigned char *)(image_addr + page_size);
1928 kernel_size = hdr->kernel_size;
1929 }
Matthew Qinbb7923d2015-02-09 10:56:09 +08001930 }
1931
1932 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001933 * Update the kernel/ramdisk/tags address if the boot image header
1934 * has default values, these default values come from mkbootimg when
1935 * the boot image is flashed using fastboot flash:raw
1936 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001937 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001938
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001939 /* Get virtual addresses since the hdr saves physical addresses. */
1940 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
1941 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
1942 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001943
Matthew Qinbb7923d2015-02-09 10:56:09 +08001944 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001945 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08001946 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05301947 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
1948 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
1949 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001950 {
Mayank Grovere559cec2017-10-17 15:12:03 +05301951 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001952 return -1;
1953 }
1954
1955#ifndef DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05301956 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
1957 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001958 {
Mayank Grovere559cec2017-10-17 15:12:03 +05301959 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001960 return -1;
1961 }
1962#endif
1963
Matthew Qin49e51fa2015-02-09 10:40:45 +08001964 /* Move kernel, ramdisk and device tree to correct address */
Matthew Qinbb7923d2015-02-09 10:56:09 +08001965 memmove((void*) hdr->kernel_addr, kernel_start_addr, kernel_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001966 memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001967
Matthew Qin49e51fa2015-02-09 10:40:45 +08001968 #if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05301969 if(dt_size) {
Matthew Qin49e51fa2015-02-09 10:40:45 +08001970 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
1971 table = (struct dt_table*) dt_table_offset;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001972
Matthew Qin49e51fa2015-02-09 10:40:45 +08001973 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
1974 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
1975 return -1;
1976 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001977
P.V. Phani Kumar82916762016-03-09 09:20:19 +05301978 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
1979 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05301980 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05301981 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
1982 return -1;
1983 }
1984
Matthew Qin49e51fa2015-02-09 10:40:45 +08001985 /* Find index of device tree within device tree table */
1986 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
1987 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
1988 return -1;
1989 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001990
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05301991 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
1992 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
1993 return -1;
1994 }
1995
1996 /* Ensure we are not overshooting dt_size with the dt_entry selected */
Parth Dixit4097b622016-03-15 14:42:27 +05301997 if ((dt_entry.offset + dt_entry.size) > dt_size) {
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05301998 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
1999 return -1;
2000 }
2001
Matthew Qin271927e2015-03-31 22:07:07 -04002002 if (is_gzip_package((unsigned char *)dt_table_offset + dt_entry.offset, dt_entry.size))
2003 {
2004 unsigned int compressed_size = 0;
2005 out_addr += out_len;
2006 out_avai_len -= out_len;
Matthew Qin0b15b322015-05-19 05:20:54 -04002007 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002008 rc = decompress((unsigned char *)dt_table_offset + dt_entry.offset,
2009 dt_entry.size, out_addr, out_avai_len,
2010 &compressed_size, &dtb_size);
2011 if (rc)
2012 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002013 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002014 ASSERT(0);
2015 }
2016
Matthew Qin0b15b322015-05-19 05:20:54 -04002017 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002018 best_match_dt_addr = out_addr;
2019 } else {
2020 best_match_dt_addr = (unsigned char *)dt_table_offset + dt_entry.offset;
2021 dtb_size = dt_entry.size;
2022 }
2023
Matthew Qin49e51fa2015-02-09 10:40:45 +08002024 /* Validate and Read device device tree in the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302025 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
2026 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002027 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302028 dprintf(CRITICAL, "Device tree addresses are not valid\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002029 return -1;
2030 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002031
Matthew Qin271927e2015-03-31 22:07:07 -04002032 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002033 } else {
2034 /* Validate the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302035 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2036 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002037 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302038 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002039 return -1;
2040 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002041 /*
2042 * If appended dev tree is found, update the atags with
2043 * memory address to the DTB appended location on RAM.
2044 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302045 *
2046 * Make sure everything from scratch address is read before next step!
2047 * In case of dtbo, this API is going to read dtbo on scratch.
Matthew Qin49e51fa2015-02-09 10:40:45 +08002048 */
2049 void *dtb;
Ameya Thakur10a33452016-06-13 14:24:26 -07002050 dtb = dev_tree_appended(
2051 (void*)(image_addr + page_size +
2052 patched_kernel_hdr_size),
2053 hdr->kernel_size, dtb_offset,
2054 (void *)hdr->tags_addr);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002055 if (!dtb) {
2056 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002057 return -1;
2058 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002059 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002060 #endif
Shashank Mittal23b8f422010-04-16 19:27:21 -07002061
Stanimir Varbanov69ec5462013-07-18 18:17:42 +03002062 if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
2063 target_load_ssd_keystore();
2064
Shashank Mittal23b8f422010-04-16 19:27:21 -07002065unified_boot:
Shashank Mittal23b8f422010-04-16 19:27:21 -07002066
Dima Zavin77e41f32013-03-06 16:10:43 -08002067 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002068 (const char *)hdr->cmdline, board_machtype(),
Shashank Mittal23b8f422010-04-16 19:27:21 -07002069 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2070
2071 return 0;
2072}
2073
Dima Zavin214cc642009-01-26 11:16:21 -08002074int boot_linux_from_flash(void)
2075{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302076 boot_img_hdr *hdr = (void*) buf;
Dima Zavin214cc642009-01-26 11:16:21 -08002077 struct ptentry *ptn;
2078 struct ptable *ptable;
2079 unsigned offset = 0;
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002080
Shashank Mittalcd98d472011-08-02 14:29:24 -07002081 unsigned char *image_addr = 0;
2082 unsigned kernel_actual;
2083 unsigned ramdisk_actual;
2084 unsigned imagesize_actual;
vijay kumar8f53e362015-11-24 13:38:11 +05302085 unsigned second_actual = 0;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002086
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002087#if DEVICE_TREE
Monika Singh292b3e92018-03-17 22:40:23 +05302088 struct dt_table *table = NULL;
Joel Kingaa335dc2013-06-03 16:11:08 -07002089 struct dt_entry dt_entry;
vijay kumar8f53e362015-11-24 13:38:11 +05302090 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08002091 uint32_t dt_actual;
Monika Singh292b3e92018-03-17 22:40:23 +05302092 uint32_t dt_hdr_size = 0;
Vivek Kumar07bd0862018-04-10 14:19:23 +05302093 uint32_t dtb_offset = 0;
vijay kumar8f53e362015-11-24 13:38:11 +05302094 unsigned int dtb_size = 0;
2095 unsigned char *best_match_dt_addr = NULL;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002096#endif
2097
David Ng183a7422009-12-07 14:55:21 -08002098 if (target_is_emmc_boot()) {
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302099 hdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
David Ng183a7422009-12-07 14:55:21 -08002100 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
2101 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
2102 return -1;
2103 }
2104 goto continue_boot;
2105 }
2106
Dima Zavin214cc642009-01-26 11:16:21 -08002107 ptable = flash_get_ptable();
2108 if (ptable == NULL) {
2109 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2110 return -1;
2111 }
2112
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002113 if(!boot_into_recovery)
2114 {
2115 ptn = ptable_find(ptable, "boot");
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002116
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002117 if (ptn == NULL) {
2118 dprintf(CRITICAL, "ERROR: No boot partition found\n");
2119 return -1;
2120 }
2121 }
2122 else
2123 {
2124 ptn = ptable_find(ptable, "recovery");
2125 if (ptn == NULL) {
2126 dprintf(CRITICAL, "ERROR: No recovery partition found\n");
2127 return -1;
2128 }
Dima Zavin214cc642009-01-26 11:16:21 -08002129 }
2130
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302131 /* Read boot.img header from flash */
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002132 if (flash_read(ptn, offset, buf, page_size)) {
Dima Zavin214cc642009-01-26 11:16:21 -08002133 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
2134 return -1;
2135 }
Dima Zavin214cc642009-01-26 11:16:21 -08002136
2137 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002138 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Dima Zavin214cc642009-01-26 11:16:21 -08002139 return -1;
2140 }
2141
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002142 if (hdr->page_size != page_size) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002143 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 -08002144 return -1;
2145 }
2146
Kishor PK9e91b592017-05-24 12:14:55 +05302147 image_addr = (unsigned char *)target_get_scratch_address();
2148 memcpy(image_addr, (void *)buf, page_size);
vijay kumar287bb542015-09-29 13:01:52 +05302149
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002150 /*
2151 * Update the kernel/ramdisk/tags address if the boot image header
2152 * has default values, these default values come from mkbootimg when
2153 * the boot image is flashed using fastboot flash:raw
2154 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002155 update_ker_tags_rdisk_addr(hdr, false);
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002156
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002157 /* Get virtual addresses since the hdr saves physical addresses. */
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002158 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
2159 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
2160 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
2161
2162 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
2163 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Mayank Grover032736f2017-07-14 20:34:51 +05302164 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002165
Kishor PK9e91b592017-05-24 12:14:55 +05302166 /* ensure commandline is terminated */
2167 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
2168
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002169 /* Check if the addresses in the header are valid. */
2170 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05302171 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_actual) ||
2172 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
2173 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002174 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302175 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002176 return -1;
2177 }
2178
2179#ifndef DEVICE_TREE
Kishor PKd8ddcad2017-07-27 13:53:57 +05302180 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + page_size)) {
Mayank Grover032736f2017-07-14 20:34:51 +05302181 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2182 return -1;
2183 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05302184 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302185
Mayank Grovere559cec2017-10-17 15:12:03 +05302186 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2187 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302188 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302189 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302190 return -1;
2191 }
2192#else
2193
2194#ifndef OSVERSION_IN_BOOTIMAGE
2195 dt_size = hdr->dt_size;
2196#endif
Mayank Grover032736f2017-07-14 20:34:51 +05302197 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05302198 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 +05302199 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2200 return -1;
2201 }
2202
Kishor PKd8ddcad2017-07-27 13:53:57 +05302203 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302204
Mayank Grovere559cec2017-10-17 15:12:03 +05302205 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size) ||
2206 check_ddr_addr_range_bound(hdr->tags_addr, dt_size))
Mayank Grover032736f2017-07-14 20:34:51 +05302207 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302208 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Mayank Grover032736f2017-07-14 20:34:51 +05302209 return -1;
2210 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002211#endif
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002212
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302213 /* Read full boot.img from flash */
2214 dprintf(INFO, "Loading (%s) image (%d): start\n",
2215 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2216 bs_set_timestamp(BS_KERNEL_LOAD_START);
2217
2218 if (UINT_MAX - page_size < imagesize_actual)
2219 {
2220 dprintf(CRITICAL,"Integer overflow detected in bootimage header fields %u %s\n", __LINE__,__func__);
2221 return -1;
2222 }
2223
2224 /*Check the availability of RAM before reading boot image + max signature length from flash*/
2225 if (target_get_max_flash_size() < (imagesize_actual + page_size))
2226 {
2227 dprintf(CRITICAL, "bootimage size is greater than DDR can hold\n");
2228 return -1;
2229 }
2230
2231 offset = page_size;
2232 /* Read image without signature and header */
2233 if (flash_read(ptn, offset, (void *)(image_addr + offset), imagesize_actual - page_size))
2234 {
2235 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
2236 return -1;
2237 }
2238
2239 dprintf(INFO, "Loading (%s) image (%d): done\n",
2240 (!boot_into_recovery ? "boot" : "recovery"), imagesize_actual);
2241 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
2242
Shashank Mittalcd98d472011-08-02 14:29:24 -07002243 /* Authenticate Kernel */
Deepa Dinamani23b60d42013-06-24 18:10:52 -07002244 if(target_use_signed_kernel() && (!device.is_unlocked))
Shashank Mittalcd98d472011-08-02 14:29:24 -07002245 {
Shashank Mittalcd98d472011-08-02 14:29:24 -07002246 offset = imagesize_actual;
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302247
Shashank Mittalcd98d472011-08-02 14:29:24 -07002248 /* Read signature */
2249 if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
2250 {
2251 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002252 return -1;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002253 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002254
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05302255 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302256 }
2257 offset = page_size;
2258 if(hdr->second_size != 0) {
2259 if (UINT_MAX - offset < second_actual)
2260 {
2261 dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
2262 return -1;
vijay kumar8f53e362015-11-24 13:38:11 +05302263 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302264 offset += second_actual;
2265 /* Second image loading not implemented. */
2266 ASSERT(0);
2267 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302268 /* Move kernel and ramdisk to correct address */
2269 memmove((void*) hdr->kernel_addr, (char*) (image_addr + page_size), hdr->kernel_size);
2270 memmove((void*) hdr->ramdisk_addr, (char*) (image_addr + page_size + kernel_actual), hdr->ramdisk_size);
2271
2272#if DEVICE_TREE
2273 if(dt_size != 0) {
2274
2275 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2276
2277 table = (struct dt_table*) dt_table_offset;
2278
2279 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2280 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2281 return -1;
2282 }
2283
2284 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2285 goes beyound hdr->dt_size*/
2286 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
2287 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2288 return -1;
2289 }
2290
2291 /* Find index of device tree within device tree table */
2292 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2293 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2294 return -1;
2295 }
2296
2297 /* Validate and Read device device tree in the "tags_add */
2298 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size) ||
2299 check_ddr_addr_range_bound(hdr->tags_addr, dt_entry.size))
2300 {
2301 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2302 return -1;
2303 }
2304
2305 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2306 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2307 return -1;
2308 }
2309
2310 /* Ensure we are not overshooting dt_size with the dt_entry selected */
2311 if ((dt_entry.offset + dt_entry.size) > dt_size) {
2312 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2313 return -1;
2314 }
2315
2316 best_match_dt_addr = (unsigned char *)table + dt_entry.offset;
2317 dtb_size = dt_entry.size;
2318 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Vivek Kumar07bd0862018-04-10 14:19:23 +05302319
2320 } else {
2321 /* Validate the tags_addr */
2322 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2323 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
2324 {
2325 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2326 return -1;
2327 }
2328 /*
2329 * If appended dev tree is found, update the atags with
2330 * memory address to the DTB appended location on RAM.
2331 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302332 *
2333 * Make sure everything from scratch address is read before next step!
2334 * In case of dtbo, this API is going to read dtbo on scratch.
Vivek Kumar07bd0862018-04-10 14:19:23 +05302335 */
2336 void *dtb = NULL;
2337 dtb = dev_tree_appended((void*)(image_addr + page_size ),hdr->kernel_size, dtb_offset, (void *)hdr->tags_addr);
2338 if (!dtb) {
2339 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
2340 return -1;
2341 }
2342 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302343#endif
2344 if(target_use_signed_kernel() && (!device.is_unlocked))
2345 {
Shashank Mittal162244e2011-08-08 19:01:25 -07002346 /* Make sure everything from scratch address is read before next step!*/
Shashank Mittala0032282011-08-26 14:50:11 -07002347 if(device.is_tampered)
Shashank Mittal162244e2011-08-08 19:01:25 -07002348 {
2349 write_device_info_flash(&device);
2350 }
Channagoud Kadabi5c86fe32012-02-16 10:58:48 +05302351#if USE_PCOM_SECBOOT
2352 set_tamper_flag(device.is_tampered);
2353#endif
Shashank Mittalcd98d472011-08-02 14:29:24 -07002354 }
David Ng183a7422009-12-07 14:55:21 -08002355continue_boot:
Dima Zavin214cc642009-01-26 11:16:21 -08002356
Dima Zavin214cc642009-01-26 11:16:21 -08002357 /* TODO: create/pass atags to kernel */
2358
Ajay Dudanie28a6072011-07-01 13:59:46 -07002359 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002360 (const char *)hdr->cmdline, board_machtype(),
Dima Zavin214cc642009-01-26 11:16:21 -08002361 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2362
2363 return 0;
2364}
Brian Swetland9c4c0752009-01-25 16:23:50 -08002365
Shashank Mittal162244e2011-08-08 19:01:25 -07002366void write_device_info_mmc(device_info *dev)
2367{
Shashank Mittal162244e2011-08-08 19:01:25 -07002368 unsigned long long ptn = 0;
2369 unsigned long long size;
2370 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002371 uint8_t lun = 0;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002372 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302373 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002374
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002375 if (devinfo_present)
2376 index = partition_get_index("devinfo");
2377 else
2378 index = partition_get_index("aboot");
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002379
Shashank Mittal162244e2011-08-08 19:01:25 -07002380 ptn = partition_get_offset(index);
2381 if(ptn == 0)
2382 {
2383 return;
2384 }
2385
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002386 lun = partition_get_lun(index);
2387 mmc_set_lun(lun);
2388
Shashank Mittal162244e2011-08-08 19:01:25 -07002389 size = partition_get_size(index);
2390
Mayank Groverddd348d2018-01-23 14:07:09 +05302391 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2392 mmc_blocksize_mask);
2393 if (device_info_sz == UINT_MAX)
2394 {
2395 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2396 return;
2397 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002398
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002399 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302400 ret = mmc_write(ptn, device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002401 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302402 ret = mmc_write((ptn + size - device_info_sz), device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002403 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002404 {
2405 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002406 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002407 }
2408}
2409
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002410void read_device_info_mmc(struct device_info *info)
Shashank Mittal162244e2011-08-08 19:01:25 -07002411{
Shashank Mittal162244e2011-08-08 19:01:25 -07002412 unsigned long long ptn = 0;
2413 unsigned long long size;
2414 int index = INVALID_PTN;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002415 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302416 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002417
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002418 if ((index = partition_get_index("devinfo")) < 0)
2419 {
2420 devinfo_present = false;
2421 index = partition_get_index("aboot");
2422 }
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002423
Shashank Mittal162244e2011-08-08 19:01:25 -07002424 ptn = partition_get_offset(index);
2425 if(ptn == 0)
2426 {
2427 return;
2428 }
2429
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002430 mmc_set_lun(partition_get_lun(index));
2431
Shashank Mittal162244e2011-08-08 19:01:25 -07002432 size = partition_get_size(index);
2433
Mayank Groverddd348d2018-01-23 14:07:09 +05302434 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2435 mmc_blocksize_mask);
2436 if (device_info_sz == UINT_MAX)
2437 {
2438 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2439 return;
2440 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002441
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002442 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302443 ret = mmc_read(ptn, (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002444 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302445 ret = mmc_read((ptn + size - device_info_sz), (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002446 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002447 {
2448 dprintf(CRITICAL, "ERROR: Cannot read device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002449 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002450 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002451}
2452
2453void write_device_info_flash(device_info *dev)
2454{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002455 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002456 struct ptentry *ptn;
2457 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002458 if(info == NULL)
2459 {
2460 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2461 ASSERT(0);
2462 }
2463 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002464 ptable = flash_get_ptable();
2465 if (ptable == NULL)
2466 {
2467 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2468 return;
2469 }
2470
2471 ptn = ptable_find(ptable, "devinfo");
2472 if (ptn == NULL)
2473 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002474 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002475 return;
2476 }
2477
Mayank Groverdedbc892017-10-24 13:41:34 +05302478 memset(info, 0, BOOT_IMG_MAX_PAGE_SIZE);
Shashank Mittal162244e2011-08-08 19:01:25 -07002479 memcpy(info, dev, sizeof(device_info));
2480
2481 if (flash_write(ptn, 0, (void *)info_buf, page_size))
2482 {
2483 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2484 return;
2485 }
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002486 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002487}
2488
vijay kumarc65876c2015-04-24 13:29:16 +05302489static int read_allow_oem_unlock(device_info *dev)
2490{
vijay kumarc65876c2015-04-24 13:29:16 +05302491 unsigned offset;
2492 int index;
2493 unsigned long long ptn;
2494 unsigned long long ptn_size;
2495 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002496 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302497
vijay kumarca2e6812015-07-08 20:28:25 +05302498 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302499 if (index == INVALID_PTN)
2500 {
vijay kumarca2e6812015-07-08 20:28:25 +05302501 index = partition_get_index(frp_ptns[1]);
2502 if (index == INVALID_PTN)
2503 {
2504 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2505 return -1;
2506 }
vijay kumarc65876c2015-04-24 13:29:16 +05302507 }
2508
2509 ptn = partition_get_offset(index);
2510 ptn_size = partition_get_size(index);
2511 offset = ptn_size - blocksize;
2512
Mayank Grover48860402016-11-29 12:34:53 +05302513 /* Set Lun for partition */
2514 mmc_set_lun(partition_get_lun(index));
2515
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002516 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302517 {
2518 dprintf(CRITICAL, "Reading MMC failed\n");
2519 return -1;
2520 }
2521
2522 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2523 is_allow_unlock = buf[blocksize-1] & 0x01;
2524 return 0;
2525}
2526
2527static int write_allow_oem_unlock(bool allow_unlock)
2528{
vijay kumarc65876c2015-04-24 13:29:16 +05302529 unsigned offset;
vijay kumarc65876c2015-04-24 13:29:16 +05302530 int index;
2531 unsigned long long ptn;
2532 unsigned long long ptn_size;
2533 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002534 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302535
vijay kumarca2e6812015-07-08 20:28:25 +05302536 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302537 if (index == INVALID_PTN)
2538 {
vijay kumarca2e6812015-07-08 20:28:25 +05302539 index = partition_get_index(frp_ptns[1]);
2540 if (index == INVALID_PTN)
2541 {
2542 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2543 return -1;
2544 }
vijay kumarc65876c2015-04-24 13:29:16 +05302545 }
2546
2547 ptn = partition_get_offset(index);
2548 ptn_size = partition_get_size(index);
2549 offset = ptn_size - blocksize;
Mayank Grover48860402016-11-29 12:34:53 +05302550 mmc_set_lun(partition_get_lun(index));
vijay kumarc65876c2015-04-24 13:29:16 +05302551
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002552 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302553 {
2554 dprintf(CRITICAL, "Reading MMC failed\n");
2555 return -1;
2556 }
2557
2558 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2559 buf[blocksize-1] = allow_unlock;
2560 if (mmc_write(ptn + offset, blocksize, buf))
2561 {
2562 dprintf(CRITICAL, "Writing MMC failed\n");
2563 return -1;
2564 }
2565
2566 return 0;
2567}
2568
Shashank Mittal162244e2011-08-08 19:01:25 -07002569void read_device_info_flash(device_info *dev)
2570{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002571 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002572 struct ptentry *ptn;
2573 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002574 if(info == NULL)
2575 {
2576 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2577 ASSERT(0);
2578 }
2579 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002580 ptable = flash_get_ptable();
2581 if (ptable == NULL)
2582 {
2583 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2584 return;
2585 }
2586
2587 ptn = ptable_find(ptable, "devinfo");
2588 if (ptn == NULL)
2589 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002590 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002591 return;
2592 }
2593
2594 if (flash_read(ptn, 0, (void *)info_buf, page_size))
2595 {
2596 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2597 return;
2598 }
2599
2600 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
2601 {
Shashank Mittal162244e2011-08-08 19:01:25 -07002602 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
2603 info->is_unlocked = 0;
Shashank Mittala0032282011-08-26 14:50:11 -07002604 info->is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002605 write_device_info_flash(info);
2606 }
2607 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002608 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002609}
2610
2611void write_device_info(device_info *dev)
2612{
2613 if(target_is_emmc_boot())
2614 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002615 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
2616 if(info == NULL)
2617 {
2618 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2619 ASSERT(0);
2620 }
2621 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002622 memcpy(info, dev, sizeof(struct device_info));
2623
2624#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05302625 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302626 is_secure_boot_enable()) {
2627 if((write_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
2628 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002629 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07002630 else
2631 write_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002632#else
2633 write_device_info_mmc(info);
2634#endif
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002635 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002636 }
2637 else
2638 {
2639 write_device_info_flash(dev);
2640 }
2641}
2642
Monika Singh94316462018-03-15 18:39:01 +05302643int read_rollback_index(uint32_t loc, uint64_t *roll_back_index)
2644{
2645 if (!devinfo_present) {
2646 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2647 return -EINVAL;
2648 }
2649 if (loc >= ARRAY_SIZE(device.rollback_index)) {
2650 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
2651 __func__, loc, ARRAY_SIZE(device.rollback_index));
2652 ASSERT(0);
2653 }
2654
2655 *roll_back_index = device.rollback_index[loc];
2656 return 0;
2657}
2658
2659int write_rollback_index(uint32_t loc, uint64_t roll_back_index)
2660{
2661 if (!devinfo_present) {
2662 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2663 return -EINVAL;
2664 }
2665 if (loc >= ARRAY_SIZE(device.rollback_index)) {
2666 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
2667 __func__, loc, ARRAY_SIZE(device.rollback_index));
2668 ASSERT(0);
2669 }
2670
2671 device.rollback_index[loc] = roll_back_index;
2672 write_device_info(&device);
2673 return 0;
2674}
2675
Monika Singhb0fad822018-03-15 18:50:55 +05302676int store_userkey(uint8_t *user_key, uint32_t user_key_size)
2677{
2678 if (!devinfo_present) {
2679 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2680 return -EINVAL;
2681 }
2682
2683 if (user_key_size > ARRAY_SIZE(device.user_public_key)) {
2684 dprintf(CRITICAL, "StoreUserKey, UserKeySize too large!\n");
2685 return -ENODEV;
2686 }
2687
2688 memcpy(device.user_public_key, user_key, user_key_size);
2689 device.user_public_key_length = user_key_size;
2690 write_device_info(&device);
2691 return 0;
2692}
2693
2694int erase_userkey()
2695{
2696 if (!devinfo_present) {
2697 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2698 return -EINVAL;
2699 }
2700 memset(device.user_public_key, 0, ARRAY_SIZE(device.user_public_key));
2701 device.user_public_key_length = 0;
2702 write_device_info(&device);
2703 return 0;
2704}
2705
2706int get_userkey(uint8_t **user_key, uint32_t *user_key_size)
2707{
2708 if (!devinfo_present) {
2709 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2710 return -EINVAL;
2711 }
2712 *user_key = device.user_public_key;
2713 *user_key_size = device.user_public_key_length;
2714 return 0;
2715}
2716
Shashank Mittal162244e2011-08-08 19:01:25 -07002717void read_device_info(device_info *dev)
2718{
2719 if(target_is_emmc_boot())
2720 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002721 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
2722 if(info == NULL)
2723 {
2724 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2725 ASSERT(0);
2726 }
2727 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002728
2729#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05302730 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302731 is_secure_boot_enable()) {
2732 if((read_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
2733 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002734 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07002735 else
2736 read_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002737#else
2738 read_device_info_mmc(info);
2739#endif
2740
2741 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
2742 {
2743 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
lijuang511a2b52015-08-14 20:50:51 +08002744 if (is_secure_boot_enable()) {
Channagoud Kadabi05f78ba2015-07-06 11:58:14 -07002745 info->is_unlocked = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05302746#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302747 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302748 info->is_unlock_critical = 0;
Parth Dixitddbc7352015-10-18 03:13:31 +05302749#endif
lijuang511a2b52015-08-14 20:50:51 +08002750 } else {
Channagoud Kadabi2fda4092015-07-07 13:34:11 -07002751 info->is_unlocked = 1;
Monika Singh292b3e92018-03-17 22:40:23 +05302752#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302753 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302754 info->is_unlock_critical = 1;
Parth Dixitddbc7352015-10-18 03:13:31 +05302755#endif
lijuang511a2b52015-08-14 20:50:51 +08002756 }
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002757 info->is_tampered = 0;
2758 info->charger_screen_enabled = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05302759#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302760 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302761 info->verity_mode = 1; //enforcing by default
Parth Dixitddbc7352015-10-18 03:13:31 +05302762#endif
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002763 write_device_info(info);
2764 }
2765 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002766 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002767 }
2768 else
2769 {
2770 read_device_info_flash(dev);
2771 }
2772}
2773
2774void reset_device_info()
2775{
2776 dprintf(ALWAYS, "reset_device_info called.");
Shashank Mittala0032282011-08-26 14:50:11 -07002777 device.is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002778 write_device_info(&device);
2779}
2780
2781void set_device_root()
2782{
2783 dprintf(ALWAYS, "set_device_root called.");
Shashank Mittala0032282011-08-26 14:50:11 -07002784 device.is_tampered = 1;
Shashank Mittal162244e2011-08-08 19:01:25 -07002785 write_device_info(&device);
2786}
2787
lijuang4ece1e72015-08-14 21:02:36 +08002788/* set device unlock value
2789 * Must check FRP before call this function
2790 * Need to wipe data when unlock status changed
2791 * type 0: oem unlock
2792 * type 1: unlock critical
2793 * status 0: unlock as false
2794 * status 1: lock as true
2795 */
2796void set_device_unlock_value(int type, bool status)
lijuang21f12f52015-08-22 16:22:19 +08002797{
lijuang4ece1e72015-08-14 21:02:36 +08002798 if (type == UNLOCK)
2799 device.is_unlocked = status;
Monika Singh292b3e92018-03-17 22:40:23 +05302800#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302801 else if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302802 type == UNLOCK_CRITICAL)
2803 device.is_unlock_critical = status;
Parth Dixitddbc7352015-10-18 03:13:31 +05302804#endif
lijuang4ece1e72015-08-14 21:02:36 +08002805 write_device_info(&device);
2806}
2807
2808static void set_device_unlock(int type, bool status)
2809{
2810 int is_unlocked = -1;
2811 char response[MAX_RSP_SIZE];
2812
2813 /* check device unlock status if it is as expected */
2814 if (type == UNLOCK)
2815 is_unlocked = device.is_unlocked;
Monika Singh292b3e92018-03-17 22:40:23 +05302816#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302817 if(VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302818 type == UNLOCK_CRITICAL)
2819 {
2820 is_unlocked = device.is_unlock_critical;
2821 }
Parth Dixitddbc7352015-10-18 03:13:31 +05302822#endif
lijuang4ece1e72015-08-14 21:02:36 +08002823 if (is_unlocked == status) {
2824 snprintf(response, sizeof(response), "\tDevice already : %s", (status ? "unlocked!" : "locked!"));
2825 fastboot_info(response);
2826 fastboot_okay("");
2827 return;
2828 }
2829
2830 /* status is true, it means to unlock device */
lijuang07c5d6e2018-04-23 18:32:13 +08002831 if (status && !is_allow_unlock) {
2832 fastboot_fail("oem unlock is not allowed");
2833 return;
2834 }
lijuang21f12f52015-08-22 16:22:19 +08002835
lijuang4ece1e72015-08-14 21:02:36 +08002836#if FBCON_DISPLAY_MSG
lijuang07c5d6e2018-04-23 18:32:13 +08002837 display_unlock_menu(type, status);
2838 fastboot_okay("");
2839 return;
lijuang4ece1e72015-08-14 21:02:36 +08002840#else
lijuang07c5d6e2018-04-23 18:32:13 +08002841 if (status && type == UNLOCK) {
2842 fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
2843 return;
lijuang21f12f52015-08-22 16:22:19 +08002844 }
lijuang07c5d6e2018-04-23 18:32:13 +08002845#endif
lijuang4ece1e72015-08-14 21:02:36 +08002846
2847 set_device_unlock_value(type, status);
2848
2849 /* wipe data */
2850 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05302851 memset(&msg, 0, sizeof(msg));
lijuang4ece1e72015-08-14 21:02:36 +08002852 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
2853 write_misc(0, &msg, sizeof(msg));
2854
2855 fastboot_okay("");
2856 reboot_device(RECOVERY_MODE);
lijuang21f12f52015-08-22 16:22:19 +08002857}
2858
lijuang511a2b52015-08-14 20:50:51 +08002859static bool critical_flash_allowed(const char * entry)
2860{
2861 uint32_t i = 0;
2862 if (entry == NULL)
2863 return false;
2864
2865 for (i = 0; i < ARRAY_SIZE(critical_flash_allowed_ptn); i++) {
2866 if(!strcmp(entry, critical_flash_allowed_ptn[i]))
2867 return true;
2868 }
2869 return false;
Matthew Qin271927e2015-03-31 22:07:07 -04002870}
2871
2872#if DEVICE_TREE
Amol Jadicb524072012-08-09 16:40:18 -07002873int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
2874{
2875 uint32 dt_image_offset = 0;
Amol Jadicb524072012-08-09 16:40:18 -07002876 uint32_t n;
Monika Singh292b3e92018-03-17 22:40:23 +05302877 struct dt_table *table = NULL;
Amol Jadicb524072012-08-09 16:40:18 -07002878 struct dt_entry dt_entry;
Monika Singh292b3e92018-03-17 22:40:23 +05302879 uint32_t dt_hdr_size = 0;
Amol Jadicb524072012-08-09 16:40:18 -07002880 unsigned int compressed_size = 0;
2881 unsigned int dtb_size = 0;
2882 unsigned int out_avai_len = 0;
2883 unsigned char *out_addr = NULL;
2884 unsigned char *best_match_dt_addr = NULL;
2885 int rc;
2886
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302887 boot_img_hdr *hdr = (boot_img_hdr *) (boot_image_start);
Amol Jadicb524072012-08-09 16:40:18 -07002888
Parth Dixit4097b622016-03-15 14:42:27 +05302889#ifndef OSVERSION_IN_BOOTIMAGE
2890 dt_size = hdr->dt_size;
2891#endif
2892
2893 if(dt_size != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07002894 /* add kernel offset */
2895 dt_image_offset += page_size;
2896 n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
2897 dt_image_offset += n;
2898
2899 /* add ramdisk offset */
2900 n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
2901 dt_image_offset += n;
2902
2903 /* add second offset */
2904 if(hdr->second_size != 0) {
2905 n = ROUND_TO_PAGE(hdr->second_size, page_mask);
2906 dt_image_offset += n;
2907 }
2908
2909 /* offset now point to start of dt.img */
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002910 table = (struct dt_table*)(boot_image_start + dt_image_offset);
Amol Jadicb524072012-08-09 16:40:18 -07002911
Deepa Dinamani19648b42013-09-05 17:05:55 -07002912 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07002913 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2914 return -1;
2915 }
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302916
2917 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2918 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05302919 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302920 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2921 return -1;
2922 }
2923
Joel Kingaa335dc2013-06-03 16:11:08 -07002924 /* Find index of device tree within device tree table */
2925 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Amol Jadicb524072012-08-09 16:40:18 -07002926 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2927 return -1;
2928 }
2929
Matthew Qin271927e2015-03-31 22:07:07 -04002930 best_match_dt_addr = (unsigned char *)boot_image_start + dt_image_offset + dt_entry.offset;
2931 if (is_gzip_package(best_match_dt_addr, dt_entry.size))
2932 {
2933 out_addr = (unsigned char *)target_get_scratch_address() + scratch_offset;
2934 out_avai_len = target_get_max_flash_size() - scratch_offset;
Matthew Qin0b15b322015-05-19 05:20:54 -04002935 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002936 rc = decompress(best_match_dt_addr,
2937 dt_entry.size, out_addr, out_avai_len,
2938 &compressed_size, &dtb_size);
2939 if (rc)
2940 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002941 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002942 ASSERT(0);
2943 }
2944
Matthew Qin0b15b322015-05-19 05:20:54 -04002945 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002946 best_match_dt_addr = out_addr;
2947 } else {
2948 dtb_size = dt_entry.size;
2949 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002950 /* Validate and Read device device tree in the "tags_add */
Mayank Grovere559cec2017-10-17 15:12:03 +05302951 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
2952 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002953 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302954 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002955 return -1;
2956 }
2957
Amol Jadicb524072012-08-09 16:40:18 -07002958 /* Read device device tree in the "tags_add */
Matthew Qin271927e2015-03-31 22:07:07 -04002959 memmove((void*) hdr->tags_addr, (void *)best_match_dt_addr, dtb_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07002960 } else
2961 return -1;
Amol Jadicb524072012-08-09 16:40:18 -07002962
2963 /* Everything looks fine. Return success. */
2964 return 0;
2965}
2966#endif
2967
Brian Swetland9c4c0752009-01-25 16:23:50 -08002968void cmd_boot(const char *arg, void *data, unsigned sz)
2969{
2970 unsigned kernel_actual;
2971 unsigned ramdisk_actual;
Kishor PKd8ddcad2017-07-27 13:53:57 +05302972 unsigned second_actual;
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07002973 uint32_t image_actual;
2974 uint32_t dt_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302975 boot_img_hdr *hdr = NULL;
Matthew Qinbb7923d2015-02-09 10:56:09 +08002976 struct kernel64_hdr *kptr = NULL;
Brian Swetland9c4c0752009-01-25 16:23:50 -08002977 char *ptr = ((char*) data);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07002978 int ret = 0;
2979 uint8_t dtb_copied = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08002980 unsigned int out_len = 0;
2981 unsigned int out_avai_len = 0;
2982 unsigned char *out_addr = NULL;
2983 uint32_t dtb_offset = 0;
2984 unsigned char *kernel_start_addr = NULL;
2985 unsigned int kernel_size = 0;
Matthew Qin271927e2015-03-31 22:07:07 -04002986 unsigned int scratch_offset = 0;
Saranya Chidurab4933332018-10-15 17:30:06 +05302987#if VERIFIED_BOOT_2
2988 void *dtbo_image_buf = NULL;
2989 uint32_t dtbo_image_sz = 0;
2990 void *vbmeta_image_buf = NULL;
2991 uint32_t vbmeta_image_sz = 0;
2992#endif
Monika Singh292b3e92018-03-17 22:40:23 +05302993#if !VERIFIED_BOOT_2
2994 uint32_t sig_actual = 0;
2995 uint32_t sig_size = 0;
2996#ifdef MDTP_SUPPORT
2997 static bool is_mdtp_activated = 0;
2998#endif /* MDTP_SUPPORT */
2999#endif
Matthew Qinbb7923d2015-02-09 10:56:09 +08003000
lijuang2008ff22016-03-07 17:56:27 +08003001#if FBCON_DISPLAY_MSG
3002 /* Exit keys' detection thread firstly */
3003 exit_menu_keys_detection();
3004#endif
3005
Monika Singh292b3e92018-03-17 22:40:23 +05303006#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi6d5375e2015-06-23 17:15:42 -07003007 if(target_build_variant_user() && !device.is_unlocked)
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003008 {
3009 fastboot_fail("unlock device to use this command");
lijuang2008ff22016-03-07 17:56:27 +08003010 goto boot_failed;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003011 }
3012#endif
3013
Brian Swetland9c4c0752009-01-25 16:23:50 -08003014 if (sz < sizeof(hdr)) {
3015 fastboot_fail("invalid bootimage header");
lijuang2008ff22016-03-07 17:56:27 +08003016 goto boot_failed;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003017 }
3018
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303019 hdr = (boot_img_hdr *)data;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003020
3021 /* ensure commandline is terminated */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003022 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003023
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003024 if(target_is_emmc_boot() && hdr->page_size) {
3025 page_size = hdr->page_size;
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07003026 page_mask = page_size - 1;
3027 }
3028
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003029 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
3030 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303031 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003032#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05303033#ifndef OSVERSION_IN_BOOTIMAGE
3034 dt_size = hdr->dt_size;
3035#endif
3036 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003037#endif
3038
3039 image_actual = ADD_OF(page_size, kernel_actual);
3040 image_actual = ADD_OF(image_actual, ramdisk_actual);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303041 image_actual = ADD_OF(image_actual, second_actual);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003042 image_actual = ADD_OF(image_actual, dt_actual);
3043
Kishor PK5134b332017-05-09 17:50:08 +05303044 /* Checking to prevent oob access in read_der_message_length */
3045 if (image_actual > sz) {
3046 fastboot_fail("bootimage header fields are invalid");
3047 goto boot_failed;
3048 }
Saranya Chidurab4933332018-10-15 17:30:06 +05303049
Monika Singh292b3e92018-03-17 22:40:23 +05303050#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05303051 /* Pass size of boot partition, as imgsize, to avoid
3052 read fewer bytes error */
3053 image_actual = partition_get_size(partition_get_index("boot"));
Saranya Chidurab4933332018-10-15 17:30:06 +05303054
3055 /* load and validate dtbo partition */
3056 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
3057
3058 /* load vbmeta partition */
3059 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
3060
Monika Singh292b3e92018-03-17 22:40:23 +05303061 memset(&info, 0, sizeof(bootinfo));
Saranya Chidurab4933332018-10-15 17:30:06 +05303062
3063 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(data);
3064 info.images[IMG_BOOT].imgsize = image_actual;
3065 info.images[IMG_BOOT].name = "boot";
3066 ++info.num_loaded_images;
3067
3068 /* Pass loaded dtbo image */
3069 if (dtbo_image_buf != NULL) {
3070 info.images[IMG_DTBO].image_buffer = SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
3071 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
3072 info.images[IMG_DTBO].name = "dtbo";
3073 ++info.num_loaded_images;
3074 }
3075
3076 /* Pass loaded vbmeta image */
3077 if (vbmeta_image_buf != NULL) {
3078 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
3079 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
3080 info.images[IMG_VBMETA].name = "vbmeta";
3081 ++info.num_loaded_images;
3082 }
3083
Monika Singh292b3e92018-03-17 22:40:23 +05303084 info.multi_slot_boot = partition_multislot_is_supported();
3085 if (load_image_and_auth(&info))
3086 goto boot_failed;
3087 vbcmdline = info.vbcmdline;
Saranya Chidurab4933332018-10-15 17:30:06 +05303088
3089 /* Free the buffer allocated to vbmeta post verification */
3090 if (vbmeta_image_buf != NULL) {
3091 free(vbmeta_image_buf);
3092 --info.num_loaded_images;
3093 }
Monika Singh292b3e92018-03-17 22:40:23 +05303094#else
Kishor PK5134b332017-05-09 17:50:08 +05303095 sig_size = sz - image_actual;
3096
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303097 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Monika Singh292b3e92018-03-17 22:40:23 +05303098 unsigned chk;
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303099 /* Calculate the signature length from boot image */
3100 sig_actual = read_der_message_length(
Kishor PK5134b332017-05-09 17:50:08 +05303101 (unsigned char*)(data + image_actual), sig_size);
Monika Singh292b3e92018-03-17 22:40:23 +05303102 chk = ADD_OF(image_actual, sig_actual);
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003103
Monika Singh292b3e92018-03-17 22:40:23 +05303104 if (chk > sz) {
Kishor PK5134b332017-05-09 17:50:08 +05303105 fastboot_fail("bootimage header fields are invalid");
3106 goto boot_failed;
3107 }
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003108 }
3109
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003110 // Initialize boot state before trying to verify boot.img
3111#if VERIFIED_BOOT
Channagoud Kadabi699466e2015-11-03 12:37:42 -08003112 boot_verifier_init();
Mayank Groverb337e932017-01-18 20:00:40 +05303113#endif
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003114 /* Handle overflow if the input image size is greater than
3115 * boot image buffer can hold
3116 */
Monika Singh292b3e92018-03-17 22:40:23 +05303117 if ((target_get_max_flash_size() - page_size) < image_actual)
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003118 {
3119 fastboot_fail("booimage: size is greater than boot image buffer can hold");
lijuang2008ff22016-03-07 17:56:27 +08003120 goto boot_failed;
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003121 }
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003122
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003123 /* Verify the boot image
3124 * device & page_size are initialized in aboot_init
3125 */
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003126 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003127 /* Pass size excluding signature size, otherwise we would try to
3128 * access signature beyond its length
3129 */
Monika Singh292b3e92018-03-17 22:40:23 +05303130 verify_signed_bootimg((uint32_t)data, image_actual);
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003131 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003132#ifdef MDTP_SUPPORT
3133 else
3134 {
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003135 /* fastboot boot is not allowed when MDTP is activated */
Amit Blay4aa292f2015-04-28 21:55:59 +03003136 mdtp_ext_partition_verification_t ext_partition;
Amit Blay8a510302015-08-17 09:20:01 +03003137
3138 if (!is_mdtp_activated) {
3139 ext_partition.partition = MDTP_PARTITION_NONE;
3140 mdtp_fwlock_verify_lock(&ext_partition);
3141 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003142 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003143
Amir Kotzer7c768c02016-04-13 09:08:05 +03003144 /* If mdtp state cannot be validate, block fastboot boot*/
3145 if(mdtp_activated(&is_mdtp_activated)){
3146 dprintf(CRITICAL, "mdtp_activated cannot validate state.\n");
3147 dprintf(CRITICAL, "Can not proceed with fastboot boot command.\n");
3148 goto boot_failed;
3149 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003150 if(is_mdtp_activated){
3151 dprintf(CRITICAL, "fastboot boot command is not available.\n");
lijuang2008ff22016-03-07 17:56:27 +08003152 goto boot_failed;
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003153 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003154#endif /* MDTP_SUPPORT */
Monika Singh292b3e92018-03-17 22:40:23 +05303155#endif /* VERIFIED_BOOT_2 else */
Amit Blay4aa292f2015-04-28 21:55:59 +03003156
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003157#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05303158 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303159 {
3160 /* set boot and system versions. */
3161 set_os_version((unsigned char *)data);
3162 // send root of trust
3163 if(!send_rot_command((uint32_t)device.is_unlocked))
3164 ASSERT(0);
3165 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05303166#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003167 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08003168 * Check if the kernel image is a gzip package. If yes, need to decompress it.
3169 * If not, continue booting.
3170 */
3171 if (is_gzip_package((unsigned char *)(data + page_size), hdr->kernel_size))
3172 {
3173 out_addr = (unsigned char *)target_get_scratch_address();
3174 out_addr = (unsigned char *)(out_addr + image_actual + page_size);
3175 out_avai_len = target_get_max_flash_size() - image_actual - page_size;
Saranya Chidurab4933332018-10-15 17:30:06 +05303176#if VERIFIED_BOOT_2
3177 if (dtbo_image_sz)
3178 out_avai_len -= DTBO_IMG_BUF;
3179#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04003180 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003181 ret = decompress((unsigned char *)(ptr + page_size),
3182 hdr->kernel_size, out_addr, out_avai_len,
3183 &dtb_offset, &out_len);
3184 if (ret)
3185 {
Matthew Qin0b15b322015-05-19 05:20:54 -04003186 dprintf(CRITICAL, "decompressing image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003187 ASSERT(0);
3188 }
3189
Matthew Qin0b15b322015-05-19 05:20:54 -04003190 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003191 kptr = (struct kernel64_hdr *)out_addr;
3192 kernel_start_addr = out_addr;
3193 kernel_size = out_len;
3194 } else {
3195 kptr = (struct kernel64_hdr*)((char *)data + page_size);
3196 kernel_start_addr = (unsigned char *)((char *)data + page_size);
3197 kernel_size = hdr->kernel_size;
3198 }
3199
3200 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003201 * Update the kernel/ramdisk/tags address if the boot image header
3202 * has default values, these default values come from mkbootimg when
3203 * the boot image is flashed using fastboot flash:raw
3204 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08003205 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Dima Zavin3cadfff2013-03-21 14:30:48 -07003206
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003207 /* Get virtual addresses since the hdr saves physical addresses. */
3208 hdr->kernel_addr = VA(hdr->kernel_addr);
3209 hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
3210 hdr->tags_addr = VA(hdr->tags_addr);
Brian Swetland9c4c0752009-01-25 16:23:50 -08003211
Matthew Qinbb7923d2015-02-09 10:56:09 +08003212 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003213 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08003214 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05303215 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
3216 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
3217 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003218 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303219 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003220 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003221 }
3222
Amol Jadicb524072012-08-09 16:40:18 -07003223#if DEVICE_TREE
Matthew Qin271927e2015-03-31 22:07:07 -04003224 scratch_offset = image_actual + page_size + out_len;
Amol Jadicb524072012-08-09 16:40:18 -07003225 /* find correct dtb and copy it to right location */
Matthew Qin271927e2015-03-31 22:07:07 -04003226 ret = copy_dtb(data, scratch_offset);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003227
3228 dtb_copied = !ret ? 1 : 0;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003229#else
Mayank Grovere559cec2017-10-17 15:12:03 +05303230 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
3231 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003232 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303233 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003234 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003235 }
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003236#endif
3237
3238 /* Load ramdisk & kernel */
3239 memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
Matthew Qinbb7923d2015-02-09 10:56:09 +08003240 memmove((void*) hdr->kernel_addr, (char*) (kernel_start_addr), kernel_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003241
3242#if DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05303243 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
3244 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Matthew Qinbb7923d2015-02-09 10:56:09 +08003245 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303246 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003247 goto boot_failed;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003248 }
3249
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003250 /*
3251 * If dtb is not found look for appended DTB in the kernel.
3252 * If appended dev tree is found, update the atags with
3253 * memory address to the DTB appended location on RAM.
3254 * Else update with the atags address in the kernel header
3255 */
3256 if (!dtb_copied) {
3257 void *dtb;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003258 dtb = dev_tree_appended((void*)(ptr + page_size),
3259 hdr->kernel_size, dtb_offset,
Dima Zavine63e5572013-05-03 12:23:06 -07003260 (void *)hdr->tags_addr);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003261 if (!dtb) {
3262 fastboot_fail("dtb not found");
lijuang2008ff22016-03-07 17:56:27 +08003263 goto boot_failed;
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003264 }
Amol Jadicb524072012-08-09 16:40:18 -07003265 }
3266#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08003267
3268 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07003269 fastboot_stop();
Brian Swetland9c4c0752009-01-25 16:23:50 -08003270
Dima Zavin77e41f32013-03-06 16:10:43 -08003271 boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003272 (const char*) hdr->cmdline, board_machtype(),
3273 (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
lijuang2008ff22016-03-07 17:56:27 +08003274
3275 /* fastboot already stop, it's no need to show fastboot menu */
3276 return;
3277boot_failed:
3278#if FBCON_DISPLAY_MSG
3279 /* revert to fastboot menu if boot failed */
3280 display_fastboot_menu();
3281#endif
3282 return;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003283}
3284
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003285void cmd_erase_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08003286{
3287 struct ptentry *ptn;
3288 struct ptable *ptable;
3289
3290 ptable = flash_get_ptable();
3291 if (ptable == NULL) {
3292 fastboot_fail("partition table doesn't exist");
3293 return;
3294 }
3295
3296 ptn = ptable_find(ptable, arg);
3297 if (ptn == NULL) {
3298 fastboot_fail("unknown partition name");
3299 return;
3300 }
3301
Monika Singh292b3e92018-03-17 22:40:23 +05303302 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3303 dprintf(INFO, "erasing avb_custom_key\n");
3304 if (erase_userkey()) {
3305 fastboot_fail("Erasing avb_custom_key failed");
3306 } else {
3307 fastboot_okay("");
3308 }
3309 return;
3310 }
3311
Dima Zavin214cc642009-01-26 11:16:21 -08003312 if (flash_erase(ptn)) {
3313 fastboot_fail("failed to erase partition");
3314 return;
3315 }
3316 fastboot_okay("");
3317}
3318
Bikas Gurungd48bd242010-09-04 19:54:32 -07003319
3320void cmd_erase_mmc(const char *arg, void *data, unsigned sz)
3321{
3322 unsigned long long ptn = 0;
Oliver Wangcee448d2013-10-22 18:40:13 +08003323 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003324 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003325 uint8_t lun = 0;
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303326 char *footer = NULL;
Bikas Gurungd48bd242010-09-04 19:54:32 -07003327
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003328#if VERIFIED_BOOT
3329 if(!strcmp(arg, KEYSTORE_PTN_NAME))
3330 {
3331 if(!device.is_unlocked)
3332 {
3333 fastboot_fail("unlock device to erase keystore");
3334 return;
3335 }
3336 }
3337#endif
3338
Kinson Chikf1a43512011-07-14 11:28:39 -07003339 index = partition_get_index(arg);
3340 ptn = partition_get_offset(index);
Oliver Wangcee448d2013-10-22 18:40:13 +08003341 size = partition_get_size(index);
Neeti Desaica8c9602011-10-06 11:40:00 -07003342
Monika Singhc4778b72018-05-16 11:16:42 +05303343 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3344 dprintf(INFO, "erasing avb_custom_key\n");
3345 if (erase_userkey()) {
3346 fastboot_fail("Erasing avb_custom_key failed");
3347 } else {
3348 fastboot_okay("");
3349 }
3350 return;
3351 }
3352
Kinson Chikf1a43512011-07-14 11:28:39 -07003353 if(ptn == 0) {
Neeti Desaica8c9602011-10-06 11:40:00 -07003354 fastboot_fail("Partition table doesn't exist\n");
Bikas Gurungd48bd242010-09-04 19:54:32 -07003355 return;
3356 }
Kun Liang2f1601a2013-08-12 16:29:54 +08003357
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003358 lun = partition_get_lun(index);
3359 mmc_set_lun(lun);
3360
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003361 if (platform_boot_dev_isemmc())
3362 {
3363 if (mmc_erase_card(ptn, size)) {
3364 fastboot_fail("failed to erase partition\n");
3365 return;
3366 }
3367 } else {
3368 BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE);
3369 size = partition_get_size(index);
3370 if (size > DEFAULT_ERASE_SIZE)
3371 size = DEFAULT_ERASE_SIZE;
Kun Liang2f1601a2013-08-12 16:29:54 +08003372
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003373 /* Simple inefficient version of erase. Just writing
3374 0 in first several blocks */
3375 if (mmc_write(ptn , size, (unsigned int *)out)) {
3376 fastboot_fail("failed to erase partition");
3377 return;
3378 }
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303379 /*Erase FDE metadata at the userdata footer*/
3380 if(!(strncmp(arg, "userdata", 8)))
3381 {
3382 footer = memalign(CACHE_LINE, FOOTER_SIZE);
3383 memset((void *)footer, 0, FOOTER_SIZE);
3384
3385 size = partition_get_size(index);
3386
3387 if (mmc_write((ptn + size) - FOOTER_SIZE , FOOTER_SIZE, (unsigned int *)footer)) {
3388 fastboot_fail("failed to erase userdata footer");
3389 free(footer);
3390 return;
3391 }
3392 free(footer);
3393 }
Bikas Gurungd48bd242010-09-04 19:54:32 -07003394 }
Monika Singh292b3e92018-03-17 22:40:23 +05303395#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303396 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303397 !(strncmp(arg, "userdata", 8)) &&
3398 send_delete_keys_to_tz())
Sridhar Parasuram32b30662015-07-10 13:33:22 -07003399 ASSERT(0);
3400#endif
Bikas Gurungd48bd242010-09-04 19:54:32 -07003401 fastboot_okay("");
3402}
3403
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003404void cmd_erase(const char *arg, void *data, unsigned sz)
3405{
Monika Singh292b3e92018-03-17 22:40:23 +05303406#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07003407 if (target_build_variant_user())
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003408 {
Sridhar Parasuramc32d07d2015-07-12 10:57:48 -07003409 if(!device.is_unlocked)
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003410 {
Channagoud Kadabi35297672015-06-13 11:09:49 -07003411 fastboot_fail("device is locked. Cannot erase");
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003412 return;
3413 }
3414 }
3415#endif
3416
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003417 if(target_is_emmc_boot())
3418 cmd_erase_mmc(arg, data, sz);
3419 else
3420 cmd_erase_nand(arg, data, sz);
3421}
Bikas Gurungd48bd242010-09-04 19:54:32 -07003422
Mayank Grover11ff9692018-01-11 11:54:49 +05303423/* Get the size from partiton name */
3424static void get_partition_size(const char *arg, char *response)
3425{
3426 uint64_t ptn = 0;
3427 uint64_t size;
3428 int index = INVALID_PTN;
3429
3430 index = partition_get_index(arg);
3431
3432 if (index == INVALID_PTN)
3433 {
3434 dprintf(CRITICAL, "Invalid partition index\n");
3435 return;
3436 }
3437
3438 ptn = partition_get_offset(index);
3439
3440 if(!ptn)
3441 {
3442 dprintf(CRITICAL, "Invalid partition name %s\n", arg);
3443 return;
3444 }
3445
3446 size = partition_get_size(index);
3447
3448 snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size);
3449 return;
3450}
3451
Mayank Grover52cd10a2018-03-15 12:57:54 +05303452/* Function to check partition type of a partition*/
3453static fs_signature_type
3454check_partition_fs_signature(const char *arg)
3455{
3456 fs_signature_type ret = NO_FS;
3457 int index;
3458 unsigned long long ptn;
Mayank Grover399826a2018-08-27 12:15:15 +05303459 char *buffer = memalign(CACHE_LINE, mmc_blocksize);
3460 uint32_t sb_blk_offset = 0;
3461 char *sb_buffer = buffer;
3462
Mayank Grover52cd10a2018-03-15 12:57:54 +05303463 if (!sb_buffer)
3464 {
3465 dprintf(CRITICAL, "ERROR: Failed to allocate buffer for superblock\n");
3466 goto out;
3467 }
3468
3469 /* Read super block */
3470 if ((index = partition_get_index(arg)) < 0)
3471 {
3472 dprintf(CRITICAL, "ERROR: %s() doesn't exsit\n", arg);
3473 goto out;
3474 }
3475 ptn = partition_get_offset(index);
3476 mmc_set_lun(partition_get_lun(index));
Mayank Grover399826a2018-08-27 12:15:15 +05303477 sb_blk_offset = (FS_SUPERBLOCK_OFFSET/mmc_blocksize);
3478
3479 if(mmc_read(ptn + (sb_blk_offset * mmc_blocksize),
Mayank Grover52cd10a2018-03-15 12:57:54 +05303480 (void *)sb_buffer, mmc_blocksize))
3481 {
3482 dprintf(CRITICAL, "ERROR: Failed to read Superblock\n");
3483 goto out;
3484 }
3485
Mayank Grover399826a2018-08-27 12:15:15 +05303486 if (sb_blk_offset == 0)
3487 sb_buffer += FS_SUPERBLOCK_OFFSET;
3488
3489 if (*((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])) == (uint16)EXT_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05303490 {
3491 dprintf(SPEW, "%s() Found EXT FS\n", arg);
3492 ret = EXT_FS_SIGNATURE;
3493 }
Mayank Grover399826a2018-08-27 12:15:15 +05303494 else if (*((uint32 *)(&sb_buffer[F2FS_MAGIC_OFFSET_SB])) == F2FS_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05303495 {
3496 dprintf(SPEW, "%s() Found F2FS FS\n", arg);
3497 ret = EXT_F2FS_SIGNATURE;
3498 }
3499 else
3500 {
3501 dprintf(SPEW, "%s() Reverting to default 0x%x\n",
3502 arg, *((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])));
3503 ret = NO_FS;
3504 }
3505
3506out:
Mayank Grover399826a2018-08-27 12:15:15 +05303507 if(buffer)
3508 free(buffer);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303509 return ret;
3510}
3511
Mayank Groverd38fe012018-03-13 15:33:16 +05303512/* Function to get partition type */
3513static void get_partition_type(const char *arg, char *response)
3514{
3515 uint n = 0;
Mayank Grover52cd10a2018-03-15 12:57:54 +05303516 fs_signature_type fs_signature;
Mayank Groverd38fe012018-03-13 15:33:16 +05303517
3518 if (arg == NULL ||
3519 response == NULL)
3520 {
3521 dprintf(CRITICAL, "Invalid input parameter\n");
3522 return;
3523 }
3524
3525 /* By default copy raw to response */
Mayank Grover0e559042018-04-11 17:49:30 +05303526 strlcpy(response, RAW_STR, MAX_RSP_SIZE);
Mayank Groverd38fe012018-03-13 15:33:16 +05303527
3528 /* Mark partiton type for known paritions only */
3529 for (n=0; n < ARRAY_SIZE(part_type_known); n++)
3530 {
3531 if (!strncmp(part_type_known[n].part_name, arg, strlen(arg)))
3532 {
Mayank Grover52cd10a2018-03-15 12:57:54 +05303533 /* Check partition for FS signature */
3534 fs_signature = check_partition_fs_signature(arg);
3535 switch (fs_signature)
3536 {
3537 case EXT_FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05303538 strlcpy(response, EXT_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303539 break;
3540 case EXT_F2FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05303541 strlcpy(response, F2FS_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303542 break;
3543 case NO_FS:
Mayank Grover0e559042018-04-11 17:49:30 +05303544 strlcpy(response, part_type_known[n].type_response, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303545 }
Mayank Groverd38fe012018-03-13 15:33:16 +05303546 }
3547 }
3548 return;
3549}
3550
Mayank Grover11ff9692018-01-11 11:54:49 +05303551/*
3552 * Publish the partition type & size info
3553 * fastboot getvar will publish the required information.
3554 * fastboot getvar partition_size:<partition_name>: partition size in hex
3555 * fastboot getvar partition_type:<partition_name>: partition type (ext/fat)
3556 */
3557static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
3558{
Mayank Groverd38fe012018-03-13 15:33:16 +05303559 uint8_t i;
Mayank Grover11ff9692018-01-11 11:54:49 +05303560 static bool published = false;
3561 struct partition_entry *ptn_entry =
3562 partition_get_partition_entries();
3563 memset(info, 0, sizeof(struct getvar_partition_info)* num_parts);
3564
3565 for (i = 0; i < num_parts; i++) {
3566 strlcat(info[i].part_name, (const char *)ptn_entry[i].name, MAX_RSP_SIZE);
3567 strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
3568 strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
3569
Mayank Groverd38fe012018-03-13 15:33:16 +05303570 get_partition_type(info[i].part_name, info[i].type_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05303571 get_partition_size(info[i].part_name, info[i].size_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05303572 if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
3573 {
3574 dprintf(CRITICAL, "partition size name truncated\n");
3575 return;
3576 }
3577 if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
3578 {
3579 dprintf(CRITICAL, "partition type name truncated\n");
3580 return;
3581 }
3582
3583 if (!published)
3584 {
3585 /* publish partition size & type info */
3586 fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response);
3587 fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response);
3588 }
3589 }
3590 if (!published)
3591 published = true;
3592}
3593
3594
Ajay Dudani5c761132011-04-07 20:19:04 -07003595void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
Shashank Mittal23b8f422010-04-16 19:27:21 -07003596{
3597 unsigned long long ptn = 0;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07003598 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003599 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003600 char *token = NULL;
3601 char *pname = NULL;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003602 char *sp;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003603 uint8_t lun = 0;
3604 bool lun_set = false;
Mayank Grover351a75e2017-05-30 20:06:08 +05303605 int current_active_slot = INVALID;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07003606
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003607 token = strtok_r((char *)arg, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003608 pname = token;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003609 token = strtok_r(NULL, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003610 if(token)
3611 {
3612 lun = atoi(token);
3613 mmc_set_lun(lun);
3614 lun_set = true;
3615 }
3616
Mao Jinlong226f33a2014-07-04 17:24:10 +08003617 if (pname)
Greg Grisco6e754772011-06-23 12:19:39 -07003618 {
Channagoud Kadabiad259832015-05-29 11:14:17 -07003619 if (!strncmp(pname, "frp-unlock", strlen("frp-unlock")))
3620 {
3621 if (!aboot_frp_unlock(pname, data, sz))
3622 {
3623 fastboot_info("FRP unlock successful");
3624 fastboot_okay("");
3625 }
3626 else
3627 fastboot_fail("Secret key is invalid, please update the bootloader with secret key");
3628
3629 return;
3630 }
3631
Mao Jinlong226f33a2014-07-04 17:24:10 +08003632 if (!strcmp(pname, "partition"))
3633 {
3634 dprintf(INFO, "Attempt to write partition image.\n");
3635 if (write_partition(sz, (unsigned char *) data)) {
3636 fastboot_fail("failed to write partition");
Greg Grisco6e754772011-06-23 12:19:39 -07003637 return;
3638 }
Mayank Grover11ff9692018-01-11 11:54:49 +05303639 /* Re-publish partition table */
3640 publish_getvar_partition_info(part_info, partition_get_partition_count());
Mayank Grover351a75e2017-05-30 20:06:08 +05303641
3642 /* Rescan partition table to ensure we have multislot support*/
3643 if (partition_scan_for_multislot())
3644 {
3645 current_active_slot = partition_find_active_slot();
3646 dprintf(INFO, "Multislot supported: Slot %s active",
3647 (SUFFIX_SLOT(current_active_slot)));
3648 }
3649 partition_mark_active_slot(current_active_slot);
Greg Grisco6e754772011-06-23 12:19:39 -07003650 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08003651 else
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003652 {
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003653#if VERIFIED_BOOT
3654 if(!strcmp(pname, KEYSTORE_PTN_NAME))
3655 {
3656 if(!device.is_unlocked)
3657 {
3658 fastboot_fail("unlock device to flash keystore");
3659 return;
3660 }
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +05303661 if(!boot_verify_validate_keystore((unsigned char *)data,sz))
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003662 {
3663 fastboot_fail("image is not a keystore file");
3664 return;
3665 }
3666 }
3667#endif
Mao Jinlong226f33a2014-07-04 17:24:10 +08003668 index = partition_get_index(pname);
3669 ptn = partition_get_offset(index);
3670 if(ptn == 0) {
3671 fastboot_fail("partition table doesn't exist");
3672 return;
3673 }
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003674
Mayank Grover351a75e2017-05-30 20:06:08 +05303675 if (!strncmp(pname, "boot", strlen("boot"))
3676 || !strcmp(pname, "recovery"))
3677 {
Mao Jinlong226f33a2014-07-04 17:24:10 +08003678 if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
3679 fastboot_fail("image is not a boot image");
3680 return;
3681 }
Mayank Grover351a75e2017-05-30 20:06:08 +05303682
3683 /* Reset multislot_partition attributes in case of flashing boot */
3684 if (partition_multislot_is_supported())
3685 {
3686 partition_reset_attributes(index);
3687 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08003688 }
3689
3690 if(!lun_set)
3691 {
3692 lun = partition_get_lun(index);
3693 mmc_set_lun(lun);
3694 }
3695
3696 size = partition_get_size(index);
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05303697 if (ROUND_TO_PAGE(sz, mmc_blocksize_mask) > size) {
Mao Jinlong226f33a2014-07-04 17:24:10 +08003698 fastboot_fail("size too large");
3699 return;
3700 }
3701 else if (mmc_write(ptn , sz, (unsigned int *)data)) {
3702 fastboot_fail("flash write failure");
3703 return;
3704 }
Greg Grisco6e754772011-06-23 12:19:39 -07003705 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07003706 }
3707 fastboot_okay("");
3708 return;
3709}
3710
Ajay Dudanide984792015-03-02 09:57:41 -08003711void cmd_flash_meta_img(const char *arg, void *data, unsigned sz)
3712{
3713 int i, images;
3714 meta_header_t *meta_header;
3715 img_header_entry_t *img_header_entry;
Parth Dixit3e2d3032016-03-04 17:11:52 +05303716 /*End of the image address*/
3717 uintptr_t data_end;
3718
3719 if( (UINT_MAX - sz) > (uintptr_t)data )
3720 data_end = (uintptr_t)data + sz;
3721 else
3722 {
3723 fastboot_fail("Cannot flash: image header corrupt");
3724 return;
3725 }
3726
3727 if( data_end < ((uintptr_t)data + sizeof(meta_header_t)))
3728 {
3729 fastboot_fail("Cannot flash: image header corrupt");
3730 return;
3731 }
Ajay Dudanide984792015-03-02 09:57:41 -08003732
lijuang8ee21882016-04-19 16:57:11 +08003733 /* If device is locked:
3734 * Forbid to flash image to avoid the device to bypass the image
3735 * which with "any" name other than bootloader. Because it maybe
3736 * a meta package of all partitions.
3737 */
Monika Singh292b3e92018-03-17 22:40:23 +05303738#if VERIFIED_BOOT || VERIFIED_BOOT_2
lijuang8ee21882016-04-19 16:57:11 +08003739 if (target_build_variant_user()) {
3740 if (!device.is_unlocked) {
3741 fastboot_fail("Device is locked, meta image flashing is not allowed");
3742 return;
3743 }
Mayank Grover889be1b2017-09-12 20:12:23 +05303744
Mayank Grover912eaa62017-10-26 12:08:53 +05303745 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303746 !device.is_unlock_critical)
3747 {
lijuang8ee21882016-04-19 16:57:11 +08003748 fastboot_fail("Device is critical locked, Meta image flashing is not allowed");
3749 return;
3750 }
lijuang8ee21882016-04-19 16:57:11 +08003751 }
3752#endif
3753
Ajay Dudanide984792015-03-02 09:57:41 -08003754 meta_header = (meta_header_t*) data;
Parth Dixit3e2d3032016-03-04 17:11:52 +05303755 if( data_end < ((uintptr_t)data + meta_header->img_hdr_sz))
3756 {
3757 fastboot_fail("Cannot flash: image header corrupt");
3758 return;
3759 }
Ajay Dudanide984792015-03-02 09:57:41 -08003760 img_header_entry = (img_header_entry_t*) (data+sizeof(meta_header_t));
3761
3762 images = meta_header->img_hdr_sz / sizeof(img_header_entry_t);
3763
3764 for (i=0; i<images; i++) {
3765
3766 if((img_header_entry[i].ptn_name == NULL) ||
3767 (img_header_entry[i].start_offset == 0) ||
3768 (img_header_entry[i].size == 0))
3769 break;
Kishor PK49831502017-04-21 17:55:43 +05303770 if ((UINT_MAX - img_header_entry[i].start_offset) < (uintptr_t)data) {
3771 fastboot_fail("Integer overflow detected in start_offset of img");
3772 break;
3773 }
3774 else if ((UINT_MAX - (img_header_entry[i].start_offset + (uintptr_t)data)) < img_header_entry[i].size) {
3775 fastboot_fail("Integer overflow detected in size of img");
3776 break;
3777 }
Parth Dixit3e2d3032016-03-04 17:11:52 +05303778 if( data_end < ((uintptr_t)data + img_header_entry[i].start_offset
3779 + img_header_entry[i].size) )
3780 {
3781 fastboot_fail("Cannot flash: image size mismatch");
3782 break;
3783 }
3784
Ajay Dudanide984792015-03-02 09:57:41 -08003785 cmd_flash_mmc_img(img_header_entry[i].ptn_name,
3786 (void *) data + img_header_entry[i].start_offset,
3787 img_header_entry[i].size);
3788 }
3789
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08003790 if (!strncmp(arg, "bootloader", strlen("bootloader")))
3791 {
3792 strlcpy(device.bootloader_version, TARGET(BOARD), MAX_VERSION_LEN);
3793 strlcat(device.bootloader_version, "-", MAX_VERSION_LEN);
3794 strlcat(device.bootloader_version, meta_header->img_version, MAX_VERSION_LEN);
3795 }
3796 else
3797 {
3798 strlcpy(device.radio_version, TARGET(BOARD), MAX_VERSION_LEN);
3799 strlcat(device.radio_version, "-", MAX_VERSION_LEN);
3800 strlcat(device.radio_version, meta_header->img_version, MAX_VERSION_LEN);
3801 }
3802
3803 write_device_info(&device);
Ajay Dudanide984792015-03-02 09:57:41 -08003804 fastboot_okay("");
3805 return;
3806}
3807
Ajay Dudani5c761132011-04-07 20:19:04 -07003808void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
3809{
3810 unsigned int chunk;
wufeng.jiang813dc352015-06-02 23:02:46 -04003811 uint64_t chunk_data_sz;
Channagoud Kadabif627cf82013-09-09 14:08:20 -07003812 uint32_t *fill_buf = NULL;
3813 uint32_t fill_val;
Mayank Grover4f50bba2017-07-19 18:17:08 +05303814 uint32_t blk_sz_actual = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07003815 sparse_header_t *sparse_header;
3816 chunk_header_t *chunk_header;
Ajay Dudaniab18f022011-05-12 14:39:22 -07003817 uint32_t total_blocks = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07003818 unsigned long long ptn = 0;
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303819 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003820 int index = INVALID_PTN;
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05303821 uint32_t i;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003822 uint8_t lun = 0;
vijay kumar800255e2015-04-24 20:26:19 +05303823 /*End of the sparse image address*/
Parth Dixit64b1a482016-03-07 16:31:26 +05303824 uintptr_t data_end = (uintptr_t)data + sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07003825
Kinson Chikf1a43512011-07-14 11:28:39 -07003826 index = partition_get_index(arg);
3827 ptn = partition_get_offset(index);
3828 if(ptn == 0) {
Ajay Dudani5c761132011-04-07 20:19:04 -07003829 fastboot_fail("partition table doesn't exist");
3830 return;
3831 }
3832
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303833 size = partition_get_size(index);
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303834
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003835 lun = partition_get_lun(index);
3836 mmc_set_lun(lun);
3837
vijay kumar800255e2015-04-24 20:26:19 +05303838 if (sz < sizeof(sparse_header_t)) {
3839 fastboot_fail("size too low");
3840 return;
3841 }
3842
Ajay Dudani5c761132011-04-07 20:19:04 -07003843 /* Read and skip over sparse image header */
3844 sparse_header = (sparse_header_t *) data;
vijay kumar800255e2015-04-24 20:26:19 +05303845
Mayank Grover48bd9bb2017-07-19 12:04:16 +05303846 if (!sparse_header->blk_sz || (sparse_header->blk_sz % 4)){
3847 fastboot_fail("Invalid block size\n");
3848 return;
3849 }
3850
vijay kumar1321f342015-03-27 12:13:42 +05303851 if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
Ajay Dudani876b3282012-12-21 14:12:17 -08003852 fastboot_fail("size too large");
3853 return;
3854 }
3855
vijay kumarde4fcf62015-04-23 13:05:49 +05303856 data += sizeof(sparse_header_t);
vijay kumar800255e2015-04-24 20:26:19 +05303857
Parth Dixit64b1a482016-03-07 16:31:26 +05303858 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05303859 fastboot_fail("buffer overreads occured due to invalid sparse header");
3860 return;
3861 }
3862
vijay kumarde4fcf62015-04-23 13:05:49 +05303863 if(sparse_header->file_hdr_sz != sizeof(sparse_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07003864 {
vijay kumarde4fcf62015-04-23 13:05:49 +05303865 fastboot_fail("sparse header size mismatch");
3866 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07003867 }
3868
Ajay Dudanib06c05f2011-05-12 14:46:10 -07003869 dprintf (SPEW, "=== Sparse Image Header ===\n");
3870 dprintf (SPEW, "magic: 0x%x\n", sparse_header->magic);
3871 dprintf (SPEW, "major_version: 0x%x\n", sparse_header->major_version);
3872 dprintf (SPEW, "minor_version: 0x%x\n", sparse_header->minor_version);
3873 dprintf (SPEW, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
3874 dprintf (SPEW, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
3875 dprintf (SPEW, "blk_sz: %d\n", sparse_header->blk_sz);
3876 dprintf (SPEW, "total_blks: %d\n", sparse_header->total_blks);
3877 dprintf (SPEW, "total_chunks: %d\n", sparse_header->total_chunks);
Ajay Dudani5c761132011-04-07 20:19:04 -07003878
3879 /* Start processing chunks */
3880 for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
3881 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05303882 /* Make sure the total image size does not exceed the partition size */
3883 if(((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz) >= size) {
3884 fastboot_fail("size too large");
3885 return;
3886 }
Ajay Dudani5c761132011-04-07 20:19:04 -07003887 /* Read and skip over chunk header */
3888 chunk_header = (chunk_header_t *) data;
3889 data += sizeof(chunk_header_t);
3890
Parth Dixit64b1a482016-03-07 16:31:26 +05303891 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05303892 fastboot_fail("buffer overreads occured due to invalid sparse header");
3893 return;
3894 }
3895
Ajay Dudani5c761132011-04-07 20:19:04 -07003896 dprintf (SPEW, "=== Chunk Header ===\n");
3897 dprintf (SPEW, "chunk_type: 0x%x\n", chunk_header->chunk_type);
3898 dprintf (SPEW, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
3899 dprintf (SPEW, "total_size: 0x%x\n", chunk_header->total_sz);
3900
vijay kumar800255e2015-04-24 20:26:19 +05303901 if(sparse_header->chunk_hdr_sz != sizeof(chunk_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07003902 {
vijay kumar800255e2015-04-24 20:26:19 +05303903 fastboot_fail("chunk header size mismatch");
3904 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07003905 }
3906
wufeng.jiang813dc352015-06-02 23:02:46 -04003907 chunk_data_sz = (uint64_t)sparse_header->blk_sz * chunk_header->chunk_sz;
3908
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05303909 /* Make sure that the chunk size calculated from sparse image does not
3910 * exceed partition size
3911 */
3912 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + chunk_data_sz > size)
3913 {
3914 fastboot_fail("Chunk data size exceeds partition size");
3915 return;
3916 }
3917
Ajay Dudani5c761132011-04-07 20:19:04 -07003918 switch (chunk_header->chunk_type)
3919 {
3920 case CHUNK_TYPE_RAW:
wufeng.jiang813dc352015-06-02 23:02:46 -04003921 if((uint64_t)chunk_header->total_sz != ((uint64_t)sparse_header->chunk_hdr_sz +
Ajay Dudani5c761132011-04-07 20:19:04 -07003922 chunk_data_sz))
3923 {
3924 fastboot_fail("Bogus chunk size for chunk type Raw");
3925 return;
3926 }
3927
Parth Dixit64b1a482016-03-07 16:31:26 +05303928 if (data_end < (uintptr_t)data + chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05303929 fastboot_fail("buffer overreads occured due to invalid sparse header");
3930 return;
3931 }
3932
wufeng.jiang813dc352015-06-02 23:02:46 -04003933 /* chunk_header->total_sz is uint32,So chunk_data_sz is now less than 2^32
3934 otherwise it will return in the line above
3935 */
Ajay Dudaniab18f022011-05-12 14:39:22 -07003936 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
wufeng.jiang813dc352015-06-02 23:02:46 -04003937 (uint32_t)chunk_data_sz,
Ajay Dudaniab18f022011-05-12 14:39:22 -07003938 (unsigned int*)data))
Ajay Dudani5c761132011-04-07 20:19:04 -07003939 {
3940 fastboot_fail("flash write failure");
3941 return;
3942 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05303943 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
3944 fastboot_fail("Bogus size for RAW chunk type");
3945 return;
3946 }
Ajay Dudani5c761132011-04-07 20:19:04 -07003947 total_blocks += chunk_header->chunk_sz;
wufeng.jiang813dc352015-06-02 23:02:46 -04003948 data += (uint32_t)chunk_data_sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07003949 break;
3950
Channagoud Kadabif627cf82013-09-09 14:08:20 -07003951 case CHUNK_TYPE_FILL:
3952 if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
3953 sizeof(uint32_t)))
3954 {
3955 fastboot_fail("Bogus chunk size for chunk type FILL");
3956 return;
3957 }
3958
Mayank Grover4f50bba2017-07-19 18:17:08 +05303959 blk_sz_actual = ROUNDUP(sparse_header->blk_sz, CACHE_LINE);
3960 /* Integer overflow detected */
3961 if (blk_sz_actual < sparse_header->blk_sz)
3962 {
3963 fastboot_fail("Invalid block size");
3964 return;
3965 }
3966
3967 fill_buf = (uint32_t *)memalign(CACHE_LINE, blk_sz_actual);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07003968 if (!fill_buf)
3969 {
3970 fastboot_fail("Malloc failed for: CHUNK_TYPE_FILL");
3971 return;
3972 }
3973
Parth Dixit64b1a482016-03-07 16:31:26 +05303974 if (data_end < (uintptr_t)data + sizeof(uint32_t)) {
vijay kumar800255e2015-04-24 20:26:19 +05303975 fastboot_fail("buffer overreads occured due to invalid sparse header");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05303976 free(fill_buf);
vijay kumar800255e2015-04-24 20:26:19 +05303977 return;
3978 }
Channagoud Kadabif627cf82013-09-09 14:08:20 -07003979 fill_val = *(uint32_t *)data;
3980 data = (char *) data + sizeof(uint32_t);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07003981
3982 for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++)
3983 {
3984 fill_buf[i] = fill_val;
3985 }
3986
Gaurav Nebhwanie94cbe12016-03-17 21:16:34 +05303987 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz))
3988 {
3989 fastboot_fail("bogus size for chunk FILL type");
3990 free(fill_buf);
3991 return;
3992 }
3993
wufeng.jiang813dc352015-06-02 23:02:46 -04003994 for (i = 0; i < chunk_header->chunk_sz; i++)
Channagoud Kadabif627cf82013-09-09 14:08:20 -07003995 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05303996 /* Make sure that the data written to partition does not exceed partition size */
3997 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + sparse_header->blk_sz > size)
3998 {
3999 fastboot_fail("Chunk data size for fill type exceeds partition size");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304000 free(fill_buf);
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304001 return;
4002 }
4003
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004004 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
4005 sparse_header->blk_sz,
4006 fill_buf))
4007 {
4008 fastboot_fail("flash write failure");
4009 free(fill_buf);
4010 return;
4011 }
4012
4013 total_blocks++;
4014 }
4015
4016 free(fill_buf);
4017 break;
4018
Ajay Dudani5c761132011-04-07 20:19:04 -07004019 case CHUNK_TYPE_DONT_CARE:
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304020 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4021 fastboot_fail("bogus size for chunk DONT CARE type");
4022 return;
4023 }
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004024 total_blocks += chunk_header->chunk_sz;
4025 break;
4026
Ajay Dudani5c761132011-04-07 20:19:04 -07004027 case CHUNK_TYPE_CRC:
4028 if(chunk_header->total_sz != sparse_header->chunk_hdr_sz)
4029 {
wufeng.jiang813dc352015-06-02 23:02:46 -04004030 fastboot_fail("Bogus chunk size for chunk type CRC");
Ajay Dudani5c761132011-04-07 20:19:04 -07004031 return;
4032 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304033 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4034 fastboot_fail("bogus size for chunk CRC type");
4035 return;
4036 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004037 total_blocks += chunk_header->chunk_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304038 if ((uintptr_t)data > UINT_MAX - chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05304039 fastboot_fail("integer overflow occured");
4040 return;
4041 }
wufeng.jiang813dc352015-06-02 23:02:46 -04004042 data += (uint32_t)chunk_data_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304043 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304044 fastboot_fail("buffer overreads occured due to invalid sparse header");
4045 return;
4046 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004047 break;
4048
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004049 default:
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004050 dprintf(CRITICAL, "Unkown chunk type: %x\n",chunk_header->chunk_type);
Ajay Dudani5c761132011-04-07 20:19:04 -07004051 fastboot_fail("Unknown chunk type");
4052 return;
4053 }
4054 }
4055
Ajay Dudani0c6927b2011-05-18 11:12:16 -07004056 dprintf(INFO, "Wrote %d blocks, expected to write %d blocks\n",
4057 total_blocks, sparse_header->total_blks);
4058
4059 if(total_blocks != sparse_header->total_blks)
4060 {
4061 fastboot_fail("sparse image write failure");
4062 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004063
4064 fastboot_okay("");
4065 return;
4066}
4067
4068void cmd_flash_mmc(const char *arg, void *data, unsigned sz)
4069{
4070 sparse_header_t *sparse_header;
Ajay Dudanide984792015-03-02 09:57:41 -08004071 meta_header_t *meta_header;
Ajay Dudani5c761132011-04-07 20:19:04 -07004072
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004073#ifdef SSD_ENABLE
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08004074 /* 8 Byte Magic + 2048 Byte xml + Encrypted Data */
4075 unsigned int *magic_number = (unsigned int *) data;
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004076 int ret=0;
4077 uint32 major_version=0;
4078 uint32 minor_version=0;
4079
4080 ret = scm_svc_version(&major_version,&minor_version);
4081 if(!ret)
4082 {
4083 if(major_version >= 2)
4084 {
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004085 if( !strcmp(arg, "ssd") || !strcmp(arg, "tqs") )
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004086 {
4087 ret = encrypt_scm((uint32 **) &data, &sz);
4088 if (ret != 0) {
4089 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4090 return;
4091 }
4092
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004093 /* Protect only for SSD */
4094 if (!strcmp(arg, "ssd")) {
4095 ret = scm_protect_keystore((uint32 *) data, sz);
4096 if (ret != 0) {
4097 dprintf(CRITICAL, "ERROR: scm_protect_keystore Failed\n");
4098 return;
4099 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004100 }
4101 }
4102 else
4103 {
4104 ret = decrypt_scm_v2((uint32 **) &data, &sz);
4105 if(ret != 0)
4106 {
4107 dprintf(CRITICAL,"ERROR: Decryption Failure\n");
4108 return;
4109 }
4110 }
4111 }
4112 else
4113 {
4114 if (magic_number[0] == DECRYPT_MAGIC_0 &&
4115 magic_number[1] == DECRYPT_MAGIC_1)
4116 {
4117 ret = decrypt_scm((uint32 **) &data, &sz);
4118 if (ret != 0) {
4119 dprintf(CRITICAL, "ERROR: Invalid secure image\n");
4120 return;
4121 }
4122 }
4123 else if (magic_number[0] == ENCRYPT_MAGIC_0 &&
4124 magic_number[1] == ENCRYPT_MAGIC_1)
4125 {
4126 ret = encrypt_scm((uint32 **) &data, &sz);
4127 if (ret != 0) {
4128 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4129 return;
4130 }
4131 }
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004132 }
4133 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004134 else
Neeti Desai127b9e02012-03-20 16:11:23 -07004135 {
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004136 dprintf(CRITICAL,"INVALID SVC Version\n");
4137 return;
Neeti Desai127b9e02012-03-20 16:11:23 -07004138 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004139#endif /* SSD_ENABLE */
Neeti Desai127b9e02012-03-20 16:11:23 -07004140
Monika Singh292b3e92018-03-17 22:40:23 +05304141#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07004142 if (target_build_variant_user())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004143 {
lijuang511a2b52015-08-14 20:50:51 +08004144 /* if device is locked:
4145 * common partition will not allow to be flashed
4146 * critical partition will allow to flash image.
4147 */
4148 if(!device.is_unlocked && !critical_flash_allowed(arg)) {
4149 fastboot_fail("Partition flashing is not allowed");
4150 return;
4151 }
Mayank Grover889be1b2017-09-12 20:12:23 +05304152
lijuang511a2b52015-08-14 20:50:51 +08004153 /* if device critical is locked:
4154 * common partition will allow to be flashed
4155 * critical partition will not allow to flash image.
4156 */
Mayank Grover912eaa62017-10-26 12:08:53 +05304157 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304158 !device.is_unlock_critical &&
4159 critical_flash_allowed(arg)) {
4160 fastboot_fail("Critical partition flashing is not allowed");
4161 return;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004162 }
4163 }
4164#endif
Monika Singh292b3e92018-03-17 22:40:23 +05304165 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4166 dprintf(INFO, "flashing avb_custom_key\n");
4167 if (store_userkey(data, sz)) {
4168 fastboot_fail("Flashing avb_custom_key failed");
4169 } else {
4170 fastboot_okay("");
4171 }
4172 return;
4173 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004174
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004175 sparse_header = (sparse_header_t *) data;
Ajay Dudanide984792015-03-02 09:57:41 -08004176 meta_header = (meta_header_t *) data;
4177 if (sparse_header->magic == SPARSE_HEADER_MAGIC)
Ajay Dudani5c761132011-04-07 20:19:04 -07004178 cmd_flash_mmc_sparse_img(arg, data, sz);
Ajay Dudanide984792015-03-02 09:57:41 -08004179 else if (meta_header->magic == META_HEADER_MAGIC)
4180 cmd_flash_meta_img(arg, data, sz);
4181 else
4182 cmd_flash_mmc_img(arg, data, sz);
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004183
4184#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +05304185 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304186 (!strncmp(arg, "system", 6)) &&
4187 !device.verity_mode)
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004188 // reset dm_verity mode to enforcing
4189 device.verity_mode = 1;
4190 write_device_info(&device);
Parth Dixitddbc7352015-10-18 03:13:31 +05304191#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004192
Ajay Dudani5c761132011-04-07 20:19:04 -07004193 return;
4194}
4195
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004196void cmd_updatevol(const char *vol_name, void *data, unsigned sz)
4197{
4198 struct ptentry *sys_ptn;
4199 struct ptable *ptable;
4200
4201 ptable = flash_get_ptable();
4202 if (ptable == NULL) {
4203 fastboot_fail("partition table doesn't exist");
4204 return;
4205 }
4206
4207 sys_ptn = ptable_find(ptable, "system");
4208 if (sys_ptn == NULL) {
4209 fastboot_fail("system partition not found");
4210 return;
4211 }
4212
4213 sz = ROUND_TO_PAGE(sz, page_mask);
4214 if (update_ubi_vol(sys_ptn, vol_name, data, sz))
4215 fastboot_fail("update_ubi_vol failed");
4216 else
4217 fastboot_okay("");
4218}
4219
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004220void cmd_flash_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08004221{
4222 struct ptentry *ptn;
4223 struct ptable *ptable;
4224 unsigned extra = 0;
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304225 uint64_t partition_size = 0;
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304226 unsigned bytes_to_round_page = 0;
4227 unsigned rounded_size = 0;
Dima Zavin214cc642009-01-26 11:16:21 -08004228
Kishor PK38ed93d2017-04-25 14:19:26 +05304229 if((uintptr_t)data > (UINT_MAX - sz)) {
4230 fastboot_fail("Cannot flash: image header corrupt");
4231 return;
4232 }
4233
Dima Zavin214cc642009-01-26 11:16:21 -08004234 ptable = flash_get_ptable();
4235 if (ptable == NULL) {
4236 fastboot_fail("partition table doesn't exist");
4237 return;
4238 }
4239
4240 ptn = ptable_find(ptable, arg);
4241 if (ptn == NULL) {
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004242 dprintf(INFO, "unknown partition name (%s). Trying updatevol\n",
4243 arg);
4244 cmd_updatevol(arg, data, sz);
Dima Zavin214cc642009-01-26 11:16:21 -08004245 return;
4246 }
4247
Monika Singh292b3e92018-03-17 22:40:23 +05304248 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4249 dprintf(INFO, "flashing avb_custom_key\n");
4250 if (store_userkey(data, sz)) {
4251 fastboot_fail("Flashing avb_custom_key failed");
4252 } else {
4253 fastboot_okay("");
4254 }
4255 return;
4256 }
4257
Dima Zavin214cc642009-01-26 11:16:21 -08004258 if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) {
Kishor PK38ed93d2017-04-25 14:19:26 +05304259 if((sz > BOOT_MAGIC_SIZE) && (!memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE))) {
4260 dprintf(INFO, "Verified the BOOT_MAGIC in image header \n");
4261 } else {
4262 fastboot_fail("Image is not a boot image");
Dima Zavin214cc642009-01-26 11:16:21 -08004263 return;
4264 }
4265 }
4266
Amol Jadi5c61a952012-05-04 17:05:35 -07004267 if (!strcmp(ptn->name, "system")
Deepa Dinamani13e32c42012-03-12 14:34:17 -07004268 || !strcmp(ptn->name, "userdata")
4269 || !strcmp(ptn->name, "persist")
Sundarajan Srinivasanb063a852013-11-19 14:02:27 -08004270 || !strcmp(ptn->name, "recoveryfs")
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -08004271 || !strcmp(ptn->name, "modem"))
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004272 extra = 1;
Kishor PK38ed93d2017-04-25 14:19:26 +05304273 else {
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304274 rounded_size = ROUNDUP(sz, page_size);
4275 bytes_to_round_page = rounded_size - sz;
4276 if (bytes_to_round_page) {
4277 if (((uintptr_t)data + sz ) > (UINT_MAX - bytes_to_round_page)) {
4278 fastboot_fail("Integer overflow detected");
4279 return;
4280 }
4281 if (((uintptr_t)data + sz + bytes_to_round_page) >
4282 ((uintptr_t)target_get_scratch_address() + target_get_max_flash_size())) {
4283 fastboot_fail("Buffer size is not aligned to page_size");
4284 return;
4285 }
4286 else {
4287 memset(data + sz, 0, bytes_to_round_page);
4288 sz = rounded_size;
4289 }
Kishor PK38ed93d2017-04-25 14:19:26 +05304290 }
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304291 }
4292
Kishor PK38ed93d2017-04-25 14:19:26 +05304293 /*Checking partition_size for the possible integer overflow */
4294 partition_size = validate_partition_size(ptn);
4295
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304296 if (sz > partition_size) {
4297 fastboot_fail("Image size too large");
4298 return;
4299 }
4300
Dima Zavin214cc642009-01-26 11:16:21 -08004301 dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name);
Mayank Grover6cde9352017-06-06 18:45:23 +05304302 if ((sz > UBI_EC_HDR_SIZE) &&
4303 (!memcmp((void *)data, UBI_MAGIC, UBI_MAGIC_SIZE))) {
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004304 if (flash_ubi_img(ptn, data, sz)) {
4305 fastboot_fail("flash write failure");
4306 return;
4307 }
4308 } else {
4309 if (flash_write(ptn, extra, data, sz)) {
4310 fastboot_fail("flash write failure");
4311 return;
4312 }
Dima Zavin214cc642009-01-26 11:16:21 -08004313 }
4314 dprintf(INFO, "partition '%s' updated\n", ptn->name);
4315 fastboot_okay("");
4316}
4317
Kishor PK38ed93d2017-04-25 14:19:26 +05304318
4319static inline uint64_t validate_partition_size(struct ptentry *ptn)
4320{
4321 if (ptn->length && flash_num_pages_per_blk() && page_size) {
4322 if ((ptn->length < ( UINT_MAX / flash_num_pages_per_blk())) && ((ptn->length * flash_num_pages_per_blk()) < ( UINT_MAX / page_size))) {
4323 return ptn->length * flash_num_pages_per_blk() * page_size;
4324 }
4325 }
4326 return 0;
4327}
4328
4329
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004330void cmd_flash(const char *arg, void *data, unsigned sz)
4331{
4332 if(target_is_emmc_boot())
4333 cmd_flash_mmc(arg, data, sz);
4334 else
4335 cmd_flash_nand(arg, data, sz);
4336}
4337
Dima Zavin214cc642009-01-26 11:16:21 -08004338void cmd_continue(const char *arg, void *data, unsigned sz)
4339{
4340 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07004341 fastboot_stop();
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004342
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004343 if (target_is_emmc_boot())
4344 {
lijuanga40d6302015-07-20 20:10:13 +08004345#if FBCON_DISPLAY_MSG
lijuangde34d502016-02-26 16:04:50 +08004346 /* Exit keys' detection thread firstly */
4347 exit_menu_keys_detection();
lijuanga40d6302015-07-20 20:10:13 +08004348#endif
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004349 boot_linux_from_mmc();
4350 }
4351 else
4352 {
4353 boot_linux_from_flash();
4354 }
Dima Zavin214cc642009-01-26 11:16:21 -08004355}
4356
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004357void cmd_reboot(const char *arg, void *data, unsigned sz)
4358{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004359 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004360 fastboot_okay("");
4361 reboot_device(0);
4362}
4363
Mayank Grover351a75e2017-05-30 20:06:08 +05304364void cmd_set_active(const char *arg, void *data, unsigned sz)
4365{
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304366 char *p, *sp = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05304367 unsigned i,current_active_slot;
4368 const char *current_slot_suffix;
4369
4370 if (!partition_multislot_is_supported())
4371 {
4372 fastboot_fail("Command not supported");
4373 return;
4374 }
4375
4376 if (arg)
4377 {
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304378 p = strtok_r((char *)arg, ":", &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304379 if (p)
Mayank Grover351a75e2017-05-30 20:06:08 +05304380 {
4381 current_active_slot = partition_find_active_slot();
4382
4383 /* Check if trying to make curent slot active */
4384 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304385 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4386 (char *)suffix_delimiter, &sp);
4387
Mayank Grover5eb5f692017-07-19 20:16:04 +05304388 if (current_slot_suffix &&
4389 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304390 {
4391 fastboot_okay("Slot already set active");
4392 return;
4393 }
4394 else
4395 {
4396 for (i = 0; i < AB_SUPPORTED_SLOTS; i++)
4397 {
4398 current_slot_suffix = SUFFIX_SLOT(i);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304399 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4400 (char *)suffix_delimiter, &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304401 if (current_slot_suffix &&
4402 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304403 {
4404 partition_switch_slots(current_active_slot, i);
4405 publish_getvar_multislot_vars();
4406 fastboot_okay("");
4407 return;
4408 }
4409 }
4410 }
4411 }
4412 }
4413 fastboot_fail("Invalid slot suffix.");
4414 return;
4415}
4416
Mayank Grover98c4c742019-04-25 17:21:37 +05304417#if DYNAMIC_PARTITION_SUPPORT
4418void cmd_reboot_fastboot(const char *arg, void *data, unsigned sz)
4419{
4420 dprintf(INFO, "rebooting the device - userspace fastboot\n");
4421 if (send_recovery_cmd(RECOVERY_BOOT_FASTBOOT_CMD)) {
4422 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4423 fastboot_fail("Failed to update recovery command");
4424 return;
4425 }
4426 fastboot_okay("");
4427 reboot_device(REBOOT_MODE_UNKNOWN);
4428
4429 //shouldn't come here.
4430 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4431 return;
4432}
4433
4434void cmd_reboot_recovery(const char *arg, void *data, unsigned sz)
4435{
4436 dprintf(INFO, "rebooting the device - recovery\n");
4437 if (send_recovery_cmd(RECOVERY_BOOT_RECOVERY_CMD)) {
4438 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4439 fastboot_fail("Failed to update recovery command");
4440 return;
4441 }
4442 fastboot_okay("");
4443 reboot_device(REBOOT_MODE_UNKNOWN);
4444
4445 //shouldn't come here.
4446 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4447 return;
4448}
4449#endif
4450
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004451void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz)
4452{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004453 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004454 fastboot_okay("");
4455 reboot_device(FASTBOOT_MODE);
4456}
4457
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004458void cmd_oem_enable_charger_screen(const char *arg, void *data, unsigned size)
4459{
4460 dprintf(INFO, "Enabling charger screen check\n");
4461 device.charger_screen_enabled = 1;
4462 write_device_info(&device);
4463 fastboot_okay("");
4464}
4465
4466void cmd_oem_disable_charger_screen(const char *arg, void *data, unsigned size)
4467{
4468 dprintf(INFO, "Disabling charger screen check\n");
4469 device.charger_screen_enabled = 0;
4470 write_device_info(&device);
4471 fastboot_okay("");
4472}
4473
lijuanga25d8bb2015-09-16 13:11:52 +08004474void cmd_oem_off_mode_charger(const char *arg, void *data, unsigned size)
4475{
4476 char *p = NULL;
4477 const char *delim = " \t\n\r";
Parth Dixit407f15b2016-01-07 14:47:37 +05304478 char *sp;
lijuanga25d8bb2015-09-16 13:11:52 +08004479
4480 if (arg) {
Parth Dixit407f15b2016-01-07 14:47:37 +05304481 p = strtok_r((char *)arg, delim, &sp);
lijuanga25d8bb2015-09-16 13:11:52 +08004482 if (p) {
4483 if (!strncmp(p, "0", 1)) {
4484 device.charger_screen_enabled = 0;
4485 } else if (!strncmp(p, "1", 1)) {
4486 device.charger_screen_enabled = 1;
4487 }
4488 }
4489 }
4490
4491 /* update charger_screen_enabled value for getvar
4492 * command
4493 */
4494 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
4495 device.charger_screen_enabled);
4496
4497 write_device_info(&device);
4498 fastboot_okay("");
4499}
4500
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05304501void cmd_oem_select_display_panel(const char *arg, void *data, unsigned size)
4502{
4503 dprintf(INFO, "Selecting display panel %s\n", arg);
4504 if (arg)
4505 strlcpy(device.display_panel, arg,
4506 sizeof(device.display_panel));
4507 write_device_info(&device);
4508 fastboot_okay("");
4509}
4510
Shashank Mittal162244e2011-08-08 19:01:25 -07004511void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
4512{
lijuang4ece1e72015-08-14 21:02:36 +08004513 set_device_unlock(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05304514}
4515
4516void cmd_oem_unlock_go(const char *arg, void *data, unsigned sz)
4517{
lijuang4ece1e72015-08-14 21:02:36 +08004518 if(!device.is_unlocked) {
vijay kumarc65876c2015-04-24 13:29:16 +05304519 if(!is_allow_unlock) {
4520 fastboot_fail("oem unlock is not allowed");
4521 return;
4522 }
4523
lijuang4ece1e72015-08-14 21:02:36 +08004524 set_device_unlock_value(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05304525
lijuang4ece1e72015-08-14 21:02:36 +08004526 /* wipe data */
vijay kumarc65876c2015-04-24 13:29:16 +05304527 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05304528 memset(&msg, 0, sizeof(msg));
vijay kumarc65876c2015-04-24 13:29:16 +05304529 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
4530 write_misc(0, &msg, sizeof(msg));
4531
4532 fastboot_okay("");
4533 reboot_device(RECOVERY_MODE);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004534 }
4535 fastboot_okay("");
4536}
4537
Channagoud Kadabiad259832015-05-29 11:14:17 -07004538static int aboot_frp_unlock(char *pname, void *data, unsigned sz)
4539{
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304540 int ret=1;
4541 bool authentication_success=false;
Channagoud Kadabiad259832015-05-29 11:14:17 -07004542
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304543 /*
4544 Authentication method not implemented.
4545
4546 OEM to implement, authentication system which on successful validataion,
4547 calls write_allow_oem_unlock() with is_allow_unlock.
4548 */
4549#if 0
4550 authentication_success = oem_specific_auth_mthd();
4551#endif
4552
4553 if (authentication_success)
Channagoud Kadabiad259832015-05-29 11:14:17 -07004554 {
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304555 is_allow_unlock = true;
4556 write_allow_oem_unlock(is_allow_unlock);
4557 ret = 0;
Channagoud Kadabiad259832015-05-29 11:14:17 -07004558 }
4559 return ret;
4560}
4561
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004562void cmd_oem_lock(const char *arg, void *data, unsigned sz)
4563{
lijuang4ece1e72015-08-14 21:02:36 +08004564 set_device_unlock(UNLOCK, FALSE);
Shashank Mittal162244e2011-08-08 19:01:25 -07004565}
4566
Shashank Mittala0032282011-08-26 14:50:11 -07004567void cmd_oem_devinfo(const char *arg, void *data, unsigned sz)
4568{
lijuang511a2b52015-08-14 20:50:51 +08004569 char response[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004570 snprintf(response, sizeof(response), "\tDevice tampered: %s", (device.is_tampered ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07004571 fastboot_info(response);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004572 snprintf(response, sizeof(response), "\tDevice unlocked: %s", (device.is_unlocked ? "true" : "false"));
4573 fastboot_info(response);
Monika Singh292b3e92018-03-17 22:40:23 +05304574#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05304575 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05304576 {
4577 snprintf(response, sizeof(response), "\tDevice critical unlocked: %s",
4578 (device.is_unlock_critical ? "true" : "false"));
4579 fastboot_info(response);
4580 }
Parth Dixitddbc7352015-10-18 03:13:31 +05304581#endif
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004582 snprintf(response, sizeof(response), "\tCharger screen enabled: %s", (device.charger_screen_enabled ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07004583 fastboot_info(response);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05304584 snprintf(response, sizeof(response), "\tDisplay panel: %s", (device.display_panel));
4585 fastboot_info(response);
Shashank Mittala0032282011-08-26 14:50:11 -07004586 fastboot_okay("");
4587}
4588
lijuang511a2b52015-08-14 20:50:51 +08004589void cmd_flashing_get_unlock_ability(const char *arg, void *data, unsigned sz)
4590{
4591 char response[MAX_RSP_SIZE];
4592 snprintf(response, sizeof(response), "\tget_unlock_ability: %d", is_allow_unlock);
4593 fastboot_info(response);
4594 fastboot_okay("");
4595}
4596
4597void cmd_flashing_lock_critical(const char *arg, void *data, unsigned sz)
4598{
lijuang4ece1e72015-08-14 21:02:36 +08004599 set_device_unlock(UNLOCK_CRITICAL, FALSE);
lijuang511a2b52015-08-14 20:50:51 +08004600}
4601
4602void cmd_flashing_unlock_critical(const char *arg, void *data, unsigned sz)
4603{
lijuang4ece1e72015-08-14 21:02:36 +08004604 set_device_unlock(UNLOCK_CRITICAL, TRUE);
lijuang511a2b52015-08-14 20:50:51 +08004605}
4606
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07004607void cmd_preflash(const char *arg, void *data, unsigned sz)
4608{
4609 fastboot_okay("");
4610}
4611
Mao Flynn7b379f32015-04-20 00:28:30 +08004612static uint8_t logo_header[LOGO_IMG_HEADER_SIZE];
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304613
Mao Flynn7b379f32015-04-20 00:28:30 +08004614int splash_screen_check_header(logo_img_header *header)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304615{
Mao Flynn7b379f32015-04-20 00:28:30 +08004616 if (memcmp(header->magic, LOGO_IMG_MAGIC, 8))
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304617 return -1;
Mao Flynn7b379f32015-04-20 00:28:30 +08004618 if (header->width == 0 || header->height == 0)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304619 return -1;
4620 return 0;
4621}
4622
Mao Flynn7b379f32015-04-20 00:28:30 +08004623int splash_screen_flash()
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004624{
4625 struct ptentry *ptn;
4626 struct ptable *ptable;
Mao Flynn7b379f32015-04-20 00:28:30 +08004627 struct logo_img_header *header;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004628 struct fbcon_config *fb_display = NULL;
Channagoud Kadabib3ccf5c2014-12-03 12:39:29 -08004629
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304630 ptable = flash_get_ptable();
4631 if (ptable == NULL) {
Mao Flynn7b379f32015-04-20 00:28:30 +08004632 dprintf(CRITICAL, "ERROR: Partition table not found\n");
4633 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304634 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004635
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304636 ptn = ptable_find(ptable, "splash");
4637 if (ptn == NULL) {
4638 dprintf(CRITICAL, "ERROR: splash Partition not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004639 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304640 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004641 if (flash_read(ptn, 0, (void *)logo_header, LOGO_IMG_HEADER_SIZE)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304642 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004643 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304644 }
4645
Mao Flynn7b379f32015-04-20 00:28:30 +08004646 header = (struct logo_img_header *)logo_header;
4647 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304648 dprintf(CRITICAL, "ERROR: Boot image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004649 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304650 }
4651
4652 fb_display = fbcon_display();
4653 if (fb_display) {
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05304654 if (header->type && (header->blocks != 0) &&
4655 (UINT_MAX >= header->blocks * 512) &&
4656 ((header->blocks * 512) <= (fb_display->width *
4657 fb_display->height * (fb_display->bpp / 8)))) {
4658 /* RLE24 compressed data */
Mao Flynn7b379f32015-04-20 00:28:30 +08004659 uint8_t *base = (uint8_t *) fb_display->base + LOGO_IMG_OFFSET;
4660
4661 /* if the logo is full-screen size, remove "fbcon_clear()" */
4662 if ((header->width != fb_display->width)
4663 || (header->height != fb_display->height))
4664 fbcon_clear();
4665
4666 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
4667 (uint32_t *)base,
4668 (header->blocks * 512))) {
4669 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4670 return -1;
4671 }
4672 fbcon_extract_to_screen(header, base);
4673 return 0;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004674 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004675
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07004676 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
4677 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004678 return -1;
4679 }
4680
Vineet Bajaj99291ed2014-09-09 12:29:46 +05304681 uint8_t *base = (uint8_t *) fb_display->base;
Sachin Bhayare619e9e42017-05-15 13:10:31 +05304682 uint32_t fb_size = ROUNDUP(fb_display->width *
4683 fb_display->height *
4684 (fb_display->bpp / 8), 4096);
4685 uint32_t splash_size = ((((header->width * header->height *
4686 fb_display->bpp/8) + 511) >> 9) << 9);
4687
4688 if (splash_size > fb_size) {
4689 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
4690 return -1;
4691 }
4692
Mao Flynn7b379f32015-04-20 00:28:30 +08004693 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
4694 (uint32_t *)base,
4695 ((((header->width * header->height * fb_display->bpp/8) + 511) >> 9) << 9))) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304696 fbcon_clear();
Vineet Bajaj99291ed2014-09-09 12:29:46 +05304697 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004698 return -1;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004699 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304700 }
4701
Mao Flynn7b379f32015-04-20 00:28:30 +08004702 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304703}
4704
Mao Flynn7b379f32015-04-20 00:28:30 +08004705int splash_screen_mmc()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304706{
4707 int index = INVALID_PTN;
4708 unsigned long long ptn = 0;
4709 struct fbcon_config *fb_display = NULL;
Mao Flynn7b379f32015-04-20 00:28:30 +08004710 struct logo_img_header *header;
Mao Flynn1893a7f2015-06-03 12:03:36 +08004711 uint32_t blocksize, realsize, readsize;
4712 uint8_t *base;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304713
4714 index = partition_get_index("splash");
4715 if (index == 0) {
4716 dprintf(CRITICAL, "ERROR: splash Partition table not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004717 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304718 }
4719
4720 ptn = partition_get_offset(index);
4721 if (ptn == 0) {
4722 dprintf(CRITICAL, "ERROR: splash Partition invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004723 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304724 }
4725
Mao Flynn1893a7f2015-06-03 12:03:36 +08004726 mmc_set_lun(partition_get_lun(index));
4727
4728 blocksize = mmc_get_device_blocksize();
4729 if (blocksize == 0) {
4730 dprintf(CRITICAL, "ERROR:splash Partition invalid blocksize\n");
4731 return -1;
4732 }
4733
4734 fb_display = fbcon_display();
Channagoud Kadabidaf10a62015-07-22 11:51:55 -07004735 if (!fb_display)
4736 {
4737 dprintf(CRITICAL, "ERROR: fb config is not allocated\n");
4738 return -1;
4739 }
4740
Mao Flynn1893a7f2015-06-03 12:03:36 +08004741 base = (uint8_t *) fb_display->base;
4742
Kishor PKee5c0a32018-03-06 16:49:46 +05304743 if (mmc_read(ptn + PLL_CODES_OFFSET, (uint32_t *)(base + LOGO_IMG_OFFSET), blocksize)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304744 dprintf(CRITICAL, "ERROR: Cannot read splash image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004745 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304746 }
4747
Mao Flynn1893a7f2015-06-03 12:03:36 +08004748 header = (struct logo_img_header *)(base + LOGO_IMG_OFFSET);
Mao Flynn7b379f32015-04-20 00:28:30 +08004749 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304750 dprintf(CRITICAL, "ERROR: Splash image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004751 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304752 }
4753
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304754 if (fb_display) {
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05304755 if (header->type && (header->blocks != 0) &&
4756 (UINT_MAX >= header->blocks * 512 + LOGO_IMG_HEADER_SIZE) &&
4757 ((header->blocks * 512) <= (fb_display->width *
4758 fb_display->height * (fb_display->bpp / 8)))) {
4759 /* 1 RLE24 compressed data */
Mao Flynn1893a7f2015-06-03 12:03:36 +08004760 base += LOGO_IMG_OFFSET;
Mao Flynn7b379f32015-04-20 00:28:30 +08004761
Mao Flynn1893a7f2015-06-03 12:03:36 +08004762 realsize = header->blocks * 512;
4763 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
4764
4765 /* if the logo is not full-screen size, clean screen */
Mao Flynn7b379f32015-04-20 00:28:30 +08004766 if ((header->width != fb_display->width)
4767 || (header->height != fb_display->height))
4768 fbcon_clear();
4769
Sachin Bhayare619e9e42017-05-15 13:10:31 +05304770 uint32_t fb_size = ROUNDUP(fb_display->width *
4771 fb_display->height *
4772 (fb_display->bpp / 8), 4096);
4773
4774 if (readsize > fb_size) {
4775 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
4776 return -1;
4777 }
4778
Kishor PKee5c0a32018-03-06 16:49:46 +05304779 if (mmc_read(ptn + PLL_CODES_OFFSET + blocksize, (uint32_t *)(base + blocksize), readsize)) {
Mao Flynn7b379f32015-04-20 00:28:30 +08004780 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4781 return -1;
4782 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004783
Mao Flynn1893a7f2015-06-03 12:03:36 +08004784 fbcon_extract_to_screen(header, (base + LOGO_IMG_HEADER_SIZE));
4785 } else { /* 2 Raw BGR data */
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304786
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07004787 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
4788 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn1893a7f2015-06-03 12:03:36 +08004789 return -1;
4790 }
4791
4792 realsize = header->width * header->height * fb_display->bpp / 8;
4793 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
4794
4795 if (blocksize == LOGO_IMG_HEADER_SIZE) { /* read the content directly */
Kishor PKee5c0a32018-03-06 16:49:46 +05304796 if (mmc_read((ptn + PLL_CODES_OFFSET + LOGO_IMG_HEADER_SIZE), (uint32_t *)base, readsize)) {
Mao Flynn1893a7f2015-06-03 12:03:36 +08004797 fbcon_clear();
4798 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4799 return -1;
4800 }
4801 } else {
Kishor PKee5c0a32018-03-06 16:49:46 +05304802 if (mmc_read(ptn + PLL_CODES_OFFSET + blocksize ,
Mao Flynn1893a7f2015-06-03 12:03:36 +08004803 (uint32_t *)(base + LOGO_IMG_OFFSET + blocksize), readsize)) {
4804 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4805 return -1;
4806 }
4807 memmove(base, (base + LOGO_IMG_OFFSET + LOGO_IMG_HEADER_SIZE), realsize);
4808 }
4809 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304810 }
4811
Mao Flynn7b379f32015-04-20 00:28:30 +08004812 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304813}
4814
Mao Flynn7b379f32015-04-20 00:28:30 +08004815int fetch_image_from_partition()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304816{
4817 if (target_is_emmc_boot()) {
4818 return splash_screen_mmc();
4819 } else {
4820 return splash_screen_flash();
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004821 }
4822}
4823
Mayank Grover351a75e2017-05-30 20:06:08 +05304824void publish_getvar_multislot_vars()
4825{
4826 int i,count;
4827 static bool published = false;
4828 static char slot_count[MAX_RSP_SIZE];
4829 static struct ab_slot_info slot_info[AB_SUPPORTED_SLOTS];
4830 static char active_slot_suffix[MAX_RSP_SIZE];
4831 static char has_slot_pname[NUM_PARTITIONS][MAX_GET_VAR_NAME_SIZE];
4832 static char has_slot_reply[NUM_PARTITIONS][MAX_RSP_SIZE];
4833 const char *tmp;
4834 char tmpbuff[MAX_GET_VAR_NAME_SIZE];
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304835 signed active_slt;
Mayank Grover351a75e2017-05-30 20:06:08 +05304836
4837 if (!published)
4838 {
4839 /* Update slot meta info */
4840 count = partition_fill_partition_meta(has_slot_pname, has_slot_reply,
4841 partition_get_partition_count());
4842 for(i=0; i<count; i++)
4843 {
4844 memset(tmpbuff, 0, MAX_GET_VAR_NAME_SIZE);
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304845 snprintf(tmpbuff, MAX_GET_VAR_NAME_SIZE,"has-slot:%s",
4846 has_slot_pname[i]);
4847 strlcpy(has_slot_pname[i], tmpbuff, MAX_GET_VAR_NAME_SIZE);
Mayank Grover351a75e2017-05-30 20:06:08 +05304848 fastboot_publish(has_slot_pname[i], has_slot_reply[i]);
4849 }
4850
4851 for (i=0; i<AB_SUPPORTED_SLOTS; i++)
4852 {
4853 tmp = SUFFIX_SLOT(i);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05304854 tmp++; // to remove "_" from slot_suffix.
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304855 snprintf(slot_info[i].slot_is_unbootable, sizeof(slot_info[i].slot_is_unbootable),
4856 "slot-unbootable:%s", tmp);
4857 snprintf(slot_info[i].slot_is_active, sizeof(slot_info[i].slot_is_active),
4858 "slot-active:%s", tmp);
4859 snprintf(slot_info[i].slot_is_succesful, sizeof(slot_info[i].slot_is_succesful),
4860 "slot-success:%s", tmp);
4861 snprintf(slot_info[i].slot_retry_count, sizeof(slot_info[i].slot_retry_count),
4862 "slot-retry-count:%s", tmp);
Mayank Grover351a75e2017-05-30 20:06:08 +05304863 fastboot_publish(slot_info[i].slot_is_unbootable,
4864 slot_info[i].slot_is_unbootable_rsp);
4865 fastboot_publish(slot_info[i].slot_is_active,
4866 slot_info[i].slot_is_active_rsp);
4867 fastboot_publish(slot_info[i].slot_is_succesful,
4868 slot_info[i].slot_is_succesful_rsp);
4869 fastboot_publish(slot_info[i].slot_retry_count,
4870 slot_info[i].slot_retry_count_rsp);
4871 }
4872 fastboot_publish("current-slot", active_slot_suffix);
4873 snprintf(slot_count, sizeof(slot_count),"%d", AB_SUPPORTED_SLOTS);
4874 fastboot_publish("slot-count", slot_count);
4875 published = true;
4876 }
4877
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304878 active_slt = partition_find_active_slot();
4879 if (active_slt != INVALID)
Mayank Grover7b8a8f82017-10-27 13:07:59 +05304880 {
4881 tmp = SUFFIX_SLOT(active_slt);
4882 tmp++; // to remove "_" from slot_suffix.
4883 snprintf(active_slot_suffix, sizeof(active_slot_suffix), "%s", tmp);
4884 }
Mayank Grover2bd84bb2017-06-20 11:06:07 +05304885 else
4886 strlcpy(active_slot_suffix, "INVALID", sizeof(active_slot_suffix));
4887
Mayank Grover351a75e2017-05-30 20:06:08 +05304888 /* Update partition meta information */
4889 partition_fill_slot_meta(slot_info);
4890 return;
4891}
4892
lijuang4ece1e72015-08-14 21:02:36 +08004893void get_product_name(unsigned char *buf)
4894{
4895 snprintf((char*)buf, MAX_RSP_SIZE, "%s", TARGET(BOARD));
4896 return;
4897}
4898
Mayank Grover7b8a8f82017-10-27 13:07:59 +05304899#if PRODUCT_IOT
4900void get_bootloader_version_iot(unsigned char *buf)
4901{
4902 if (buf != NULL)
4903 {
4904 strlcpy(buf, TARGET(BOARD), MAX_VERSION_LEN);
4905 strlcat(buf, "-", MAX_VERSION_LEN);
4906 strlcat(buf, PRODUCT_IOT_VERSION, MAX_VERSION_LEN);
4907 }
4908 return;
4909}
4910#endif
4911
lijuang4ece1e72015-08-14 21:02:36 +08004912void get_bootloader_version(unsigned char *buf)
4913{
4914 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.bootloader_version);
4915 return;
4916}
4917
4918void get_baseband_version(unsigned char *buf)
4919{
4920 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.radio_version);
4921 return;
4922}
4923
Monika Singh32a09f72018-03-14 13:08:29 +05304924bool is_device_locked_critical()
4925{
4926 return device.is_unlock_critical ? false:true;
4927}
4928
lijuang4ece1e72015-08-14 21:02:36 +08004929bool is_device_locked()
4930{
4931 return device.is_unlocked ? false:true;
4932}
4933
Monika Singh32a09f72018-03-14 13:08:29 +05304934bool is_verity_enforcing()
4935{
4936 return device.verity_mode ? true:false;
4937}
4938
Amol Jadi5edf3552013-07-23 14:15:34 -07004939/* register commands and variables for fastboot */
4940void aboot_fastboot_register_commands(void)
4941{
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004942 int i;
lijuangf16461c2015-08-03 17:09:34 +08004943 char hw_platform_buf[MAX_RSP_SIZE];
Amol Jadi5edf3552013-07-23 14:15:34 -07004944
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004945 struct fastboot_cmd_desc cmd_list[] = {
lijuang511a2b52015-08-14 20:50:51 +08004946 /* By default the enabled list is empty. */
4947 {"", NULL},
4948 /* move commands enclosed within the below ifndef to here
4949 * if they need to be enabled in user build.
4950 */
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004951#ifndef DISABLE_FASTBOOT_CMDS
lijuang511a2b52015-08-14 20:50:51 +08004952 /* Register the following commands only for non-user builds */
4953 {"flash:", cmd_flash},
4954 {"erase:", cmd_erase},
4955 {"boot", cmd_boot},
4956 {"continue", cmd_continue},
4957 {"reboot", cmd_reboot},
4958 {"reboot-bootloader", cmd_reboot_bootloader},
4959 {"oem unlock", cmd_oem_unlock},
4960 {"oem unlock-go", cmd_oem_unlock_go},
4961 {"oem lock", cmd_oem_lock},
4962 {"flashing unlock", cmd_oem_unlock},
4963 {"flashing lock", cmd_oem_lock},
4964 {"flashing lock_critical", cmd_flashing_lock_critical},
4965 {"flashing unlock_critical", cmd_flashing_unlock_critical},
4966 {"flashing get_unlock_ability", cmd_flashing_get_unlock_ability},
4967 {"oem device-info", cmd_oem_devinfo},
4968 {"preflash", cmd_preflash},
4969 {"oem enable-charger-screen", cmd_oem_enable_charger_screen},
4970 {"oem disable-charger-screen", cmd_oem_disable_charger_screen},
lijuanga25d8bb2015-09-16 13:11:52 +08004971 {"oem off-mode-charge", cmd_oem_off_mode_charger},
lijuang511a2b52015-08-14 20:50:51 +08004972 {"oem select-display-panel", cmd_oem_select_display_panel},
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304973 {"set_active",cmd_set_active},
Mayank Grover98c4c742019-04-25 17:21:37 +05304974#if DYNAMIC_PARTITION_SUPPORT
4975 {"reboot-fastboot",cmd_reboot_fastboot},
4976 {"reboot-recovery",cmd_reboot_recovery},
4977#endif
Channagoud Kadabi736c4962015-08-21 11:56:52 -07004978#if UNITTEST_FW_SUPPORT
Channagoud Kadabid5ddf482015-09-28 10:31:35 -07004979 {"oem run-tests", cmd_oem_runtests},
Channagoud Kadabi736c4962015-08-21 11:56:52 -07004980#endif
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004981#endif
lijuang511a2b52015-08-14 20:50:51 +08004982 };
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004983
4984 int fastboot_cmds_count = sizeof(cmd_list)/sizeof(cmd_list[0]);
4985 for (i = 1; i < fastboot_cmds_count; i++)
4986 fastboot_register(cmd_list[i].name,cmd_list[i].cb);
4987
Amol Jadi5edf3552013-07-23 14:15:34 -07004988 /* publish variables and their values */
4989 fastboot_publish("product", TARGET(BOARD));
4990 fastboot_publish("kernel", "lk");
4991 fastboot_publish("serialno", sn_buf);
4992
Mayank Grovera64dfbe2018-05-17 14:06:34 +05304993 /*publish hw-revision major(upper 16 bits) and minor(lower 16 bits)*/
4994 snprintf(soc_version_str, MAX_RSP_SIZE, "%x", board_soc_version());
4995 fastboot_publish("hw-revision", soc_version_str);
4996
Amol Jadi5edf3552013-07-23 14:15:34 -07004997 /*
4998 * partition info is supported only for emmc partitions
4999 * Calling this for NAND prints some error messages which
5000 * is harmless but misleading. Avoid calling this for NAND
5001 * devices.
5002 */
5003 if (target_is_emmc_boot())
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305004 publish_getvar_partition_info(part_info, partition_get_partition_count());
Amol Jadi5edf3552013-07-23 14:15:34 -07005005
Mayank Grover351a75e2017-05-30 20:06:08 +05305006 if (partition_multislot_is_supported())
5007 publish_getvar_multislot_vars();
5008
Amol Jadi5edf3552013-07-23 14:15:34 -07005009 /* Max download size supported */
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005010 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5011 target_get_max_flash_size());
Amol Jadi5edf3552013-07-23 14:15:34 -07005012 fastboot_publish("max-download-size", (const char *) max_download_size);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005013 /* Is the charger screen check enabled */
5014 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
5015 device.charger_screen_enabled);
5016 fastboot_publish("charger-screen-enabled",
5017 (const char *) charger_screen_enabled);
lijuanga25d8bb2015-09-16 13:11:52 +08005018 fastboot_publish("off-mode-charge", (const char *) charger_screen_enabled);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305019 snprintf(panel_display_mode, MAX_RSP_SIZE, "%s",
5020 device.display_panel);
5021 fastboot_publish("display-panel",
5022 (const char *) panel_display_mode);
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +05305023
5024 if (target_is_emmc_boot())
5025 {
5026 mmc_blocksize = mmc_get_device_blocksize();
5027 }
5028 else
5029 {
5030 mmc_blocksize = flash_block_size();
5031 }
5032 snprintf(block_size_string, MAX_RSP_SIZE, "0x%x", mmc_blocksize);
5033 fastboot_publish("erase-block-size", (const char *) block_size_string);
5034 fastboot_publish("logical-block-size", (const char *) block_size_string);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305035#if PRODUCT_IOT
5036 get_bootloader_version_iot(&bootloader_version_string);
5037 fastboot_publish("version-bootloader", (const char *) bootloader_version_string);
5038
5039 /* Version baseband is n/a for apq iot devices */
5040 fastboot_publish("version-baseband", "N/A");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305041#else
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08005042 fastboot_publish("version-bootloader", (const char *) device.bootloader_version);
5043 fastboot_publish("version-baseband", (const char *) device.radio_version);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305044#endif
lijuangf16461c2015-08-03 17:09:34 +08005045 fastboot_publish("secure", is_secure_boot_enable()? "yes":"no");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305046 fastboot_publish("unlocked", device.is_unlocked ? "yes":"no");
lijuangf16461c2015-08-03 17:09:34 +08005047 smem_get_hw_platform_name((unsigned char *) hw_platform_buf, sizeof(hw_platform_buf));
5048 snprintf(get_variant, MAX_RSP_SIZE, "%s %s", hw_platform_buf,
5049 target_is_emmc_boot()? "eMMC":"UFS");
5050 fastboot_publish("variant", (const char *) get_variant);
lijuang65c5a822015-08-29 16:35:36 +08005051#if CHECK_BAT_VOLTAGE
lijuang102dfa92015-10-09 18:31:03 +08005052 update_battery_status();
lijuang65c5a822015-08-29 16:35:36 +08005053 fastboot_publish("battery-voltage", (const char *) battery_voltage);
lijuang102dfa92015-10-09 18:31:03 +08005054 fastboot_publish("battery-soc-ok", (const char *) battery_soc_ok);
lijuang65c5a822015-08-29 16:35:36 +08005055#endif
Mayank Grover98c4c742019-04-25 17:21:37 +05305056 if (target_dynamic_partition_supported())
5057 fastboot_publish("is-userspace", "no");
Amol Jadi5edf3552013-07-23 14:15:34 -07005058}
5059
Brian Swetland9c4c0752009-01-25 16:23:50 -08005060void aboot_init(const struct app_descriptor *app)
5061{
Shashank Mittal4f99a882010-02-01 13:58:50 -08005062 unsigned reboot_mode = 0;
Mayank Grover351a75e2017-05-30 20:06:08 +05305063 int boot_err_type = 0;
5064 int boot_slot = INVALID;
Chandan Uddarajubedca152010-06-02 23:05:15 -07005065
lijuang39831732016-01-08 17:49:02 +08005066 /* Initialise wdog to catch early lk crashes */
5067#if WDOG_SUPPORT
5068 msm_wdog_init();
5069#endif
5070
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005071 /* Setup page size information for nv storage */
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005072 if (target_is_emmc_boot())
5073 {
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005074 page_size = mmc_page_size();
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005075 page_mask = page_size - 1;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05305076 mmc_blocksize = mmc_get_device_blocksize();
5077 mmc_blocksize_mask = mmc_blocksize - 1;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005078 }
5079 else
5080 {
5081 page_size = flash_page_size();
5082 page_mask = page_size - 1;
5083 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07005084 ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
5085
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005086 read_device_info(&device);
vijay kumarc65876c2015-04-24 13:29:16 +05305087 read_allow_oem_unlock(&device);
Shashank Mittal162244e2011-08-08 19:01:25 -07005088
Mayank Grover351a75e2017-05-30 20:06:08 +05305089 /* Detect multi-slot support */
5090 if (partition_multislot_is_supported())
5091 {
5092 boot_slot = partition_find_active_slot();
5093 if (boot_slot == INVALID)
5094 {
5095 boot_into_fastboot = true;
5096 dprintf(INFO, "Active Slot: (INVALID)\n");
5097 }
5098 else
5099 {
5100 /* Setting the state of system to boot active slot */
5101 partition_mark_active_slot(boot_slot);
5102 dprintf(INFO, "Active Slot: (%s)\n", SUFFIX_SLOT(boot_slot));
5103 }
5104 }
5105
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005106 /* Display splash screen if enabled */
5107#if DISPLAY_SPLASH_SCREEN
lijuang99c02d82015-02-13 19:04:34 +08005108#if NO_ALARM_DISPLAY
5109 if (!check_alarm_boot()) {
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005110#endif
lijuang99c02d82015-02-13 19:04:34 +08005111 dprintf(SPEW, "Display Init: Start\n");
Ajay Singh Parmara7865a82015-04-16 21:27:52 -07005112#if DISPLAY_HDMI_PRIMARY
5113 if (!strlen(device.display_panel))
5114 strlcpy(device.display_panel, DISPLAY_PANEL_HDMI,
5115 sizeof(device.display_panel));
5116#endif
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005117#if ENABLE_WBC
Channagoud Kadabid801ac72015-08-26 11:21:51 -07005118 /* Wait if the display shutdown is in progress */
5119 while(pm_app_display_shutdown_in_prgs());
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005120 if (!pm_appsbl_display_init_done())
5121 target_display_init(device.display_panel);
5122 else
5123 display_image_on_screen();
5124#else
lijuang99c02d82015-02-13 19:04:34 +08005125 target_display_init(device.display_panel);
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005126#endif
lijuang99c02d82015-02-13 19:04:34 +08005127 dprintf(SPEW, "Display Init: Done\n");
5128#if NO_ALARM_DISPLAY
5129 }
5130#endif
5131#endif
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005132
Greg Griscod6250552011-06-29 14:40:23 -07005133 target_serialno((unsigned char *) sn_buf);
Ajay Dudanib06c05f2011-05-12 14:46:10 -07005134 dprintf(SPEW,"serial number: %s\n",sn_buf);
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08005135
Dhaval Patel223ec952013-07-18 14:49:44 -07005136 memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE);
5137
Matthew Qindefd5562014-07-11 18:02:40 +08005138 /*
5139 * Check power off reason if user force reset,
5140 * if yes phone will do normal boot.
5141 */
5142 if (is_user_force_reset())
5143 goto normal_boot;
5144
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005145 /* Check if we should do something other than booting up */
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005146 if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005147 {
Pavel Nedeva4c9d3a2013-05-15 14:42:34 +03005148 dprintf(ALWAYS,"dload mode key sequence detected\n");
lijuang395b5e62015-11-19 17:39:44 +08005149 reboot_device(EMERGENCY_DLOAD);
5150 dprintf(CRITICAL,"Failed to reboot into dload mode\n");
5151
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005152 boot_into_fastboot = true;
5153 }
5154 if (!boot_into_fastboot)
5155 {
5156 if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
5157 boot_into_recovery = 1;
5158 if (!boot_into_recovery &&
5159 (keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
Pavel Nedev5d91d412013-04-29 11:34:24 +03005160 boot_into_fastboot = true;
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005161 }
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005162 #if NO_KEYPAD_DRIVER
Kinson Chik0b1c8162011-08-31 16:31:57 -07005163 if (fastboot_trigger())
Pavel Nedev5d91d412013-04-29 11:34:24 +03005164 boot_into_fastboot = true;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005165 #endif
Chandan Uddarajubedca152010-06-02 23:05:15 -07005166
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005167#if USE_PON_REBOOT_REG
5168 reboot_mode = check_hard_reboot_mode();
5169#else
Ajay Dudani77421292010-10-27 19:34:06 -07005170 reboot_mode = check_reboot_mode();
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005171#endif
5172 if (reboot_mode == RECOVERY_MODE)
5173 {
Ajay Dudani77421292010-10-27 19:34:06 -07005174 boot_into_recovery = 1;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005175 }
5176 else if(reboot_mode == FASTBOOT_MODE)
5177 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005178 boot_into_fastboot = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005179 }
5180 else if(reboot_mode == ALARM_BOOT)
5181 {
Matthew Qind886f3c2014-01-17 16:52:01 +08005182 boot_reason_alarm = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005183 }
Monika Singhb0db4b82018-09-26 12:18:02 +05305184#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05305185 else if (VB_M <= target_get_vb_version())
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005186 {
Mayank Grover889be1b2017-09-12 20:12:23 +05305187 if (reboot_mode == DM_VERITY_ENFORCING)
5188 {
5189 device.verity_mode = 1;
5190 write_device_info(&device);
5191 }
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005192#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05305193 else if (reboot_mode == DM_VERITY_EIO)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005194#else
Mayank Grover889be1b2017-09-12 20:12:23 +05305195 else if (reboot_mode == DM_VERITY_LOGGING)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005196#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05305197 {
5198 device.verity_mode = 0;
5199 write_device_info(&device);
5200 }
5201 else if (reboot_mode == DM_VERITY_KEYSCLEAR)
5202 {
5203 if(send_delete_keys_to_tz())
5204 ASSERT(0);
5205 }
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005206 }
Parth Dixitddbc7352015-10-18 03:13:31 +05305207#endif
Ajay Dudani77421292010-10-27 19:34:06 -07005208
Matthew Qindefd5562014-07-11 18:02:40 +08005209normal_boot:
Pavel Nedev5d91d412013-04-29 11:34:24 +03005210 if (!boot_into_fastboot)
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005211 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005212 if (target_is_emmc_boot())
Shashank Mittala0032282011-08-26 14:50:11 -07005213 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005214 if(emmc_recovery_init())
5215 dprintf(ALWAYS,"error in emmc_recovery_init\n");
5216 if(target_use_signed_kernel())
Shashank Mittala0032282011-08-26 14:50:11 -07005217 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005218 if((device.is_unlocked) || (device.is_tampered))
5219 {
5220 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05305221 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Pavel Nedev5d91d412013-04-29 11:34:24 +03005222 #endif
5223 #if USE_PCOM_SECBOOT
5224 set_tamper_flag(device.is_tampered);
5225 #endif
5226 }
Shashank Mittala0032282011-08-26 14:50:11 -07005227 }
Amit Blay6281ebc2015-01-11 14:44:08 +02005228
Mayank Grover351a75e2017-05-30 20:06:08 +05305229retry_boot:
5230 /* Trying to boot active partition */
5231 if (partition_multislot_is_supported())
5232 {
5233 boot_slot = partition_find_boot_slot();
5234 partition_mark_active_slot(boot_slot);
5235 if (boot_slot == INVALID)
5236 goto fastboot;
5237 }
5238
5239 boot_err_type = boot_linux_from_mmc();
5240 switch (boot_err_type)
5241 {
5242 case ERR_INVALID_PAGE_SIZE:
5243 case ERR_DT_PARSE:
5244 case ERR_ABOOT_ADDR_OVERLAP:
Mayank Grover10cabbe2017-10-30 19:11:05 +05305245 case ERR_INVALID_BOOT_MAGIC:
Mayank Grover351a75e2017-05-30 20:06:08 +05305246 if(partition_multislot_is_supported())
Mayank Grover10cabbe2017-10-30 19:11:05 +05305247 {
5248 /*
5249 * Deactivate current slot, as it failed to
5250 * boot, and retry next slot.
5251 */
5252 partition_deactivate_slot(boot_slot);
Mayank Grover351a75e2017-05-30 20:06:08 +05305253 goto retry_boot;
Mayank Grover10cabbe2017-10-30 19:11:05 +05305254 }
Mayank Grover351a75e2017-05-30 20:06:08 +05305255 else
5256 break;
Mayank Grover351a75e2017-05-30 20:06:08 +05305257 default:
5258 break;
5259 /* going to fastboot menu */
5260 }
Shashank Mittala0032282011-08-26 14:50:11 -07005261 }
Pavel Nedev5d91d412013-04-29 11:34:24 +03005262 else
5263 {
5264 recovery_init();
5265 #if USE_PCOM_SECBOOT
5266 if((device.is_unlocked) || (device.is_tampered))
5267 set_tamper_flag(device.is_tampered);
5268 #endif
5269 boot_linux_from_flash();
5270 }
5271 dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
5272 "to fastboot mode.\n");
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005273 }
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005274
Mayank Grover351a75e2017-05-30 20:06:08 +05305275fastboot:
Amol Jadi5edf3552013-07-23 14:15:34 -07005276 /* We are here means regular boot did not happen. Start fastboot. */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07005277
Amol Jadi5edf3552013-07-23 14:15:34 -07005278 /* register aboot specific fastboot commands */
5279 aboot_fastboot_register_commands();
Amol Jadi57abe4c2011-05-24 15:47:27 -07005280
Amol Jadi5edf3552013-07-23 14:15:34 -07005281 /* dump partition table for debug info */
Kinson Chikf1a43512011-07-14 11:28:39 -07005282 partition_dump();
Amol Jadi5edf3552013-07-23 14:15:34 -07005283
5284 /* initialize and start fastboot */
Saranya Chidura41b34532018-10-16 12:29:52 +05305285#if !VERIFIED_BOOT_2
Amol Jadi5edf3552013-07-23 14:15:34 -07005286 fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
Saranya Chidura41b34532018-10-16 12:29:52 +05305287#else
5288 /* Add salt buffer offset at start of image address to copy VB salt */
5289 fastboot_init(ADD_SALT_BUFF_OFFSET(target_get_scratch_address()),
5290 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5291#endif
lijuang4ece1e72015-08-14 21:02:36 +08005292#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08005293 display_fastboot_menu();
lijuang4ece1e72015-08-14 21:02:36 +08005294#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08005295}
5296
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07005297uint32_t get_page_size()
5298{
5299 return page_size;
5300}
5301
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005302/*
5303 * Calculated and save hash (SHA256) for non-signed boot image.
5304 *
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005305 * @param image_addr - Boot image address
5306 * @param image_size - Size of the boot image
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005307 *
5308 * @return int - 0 on success, negative value on failure.
5309 */
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005310static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size)
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005311{
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005312 unsigned int digest[8];
5313#if IMAGE_VERIF_ALGO_SHA1
5314 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
5315#else
5316 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
5317#endif
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005318
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005319 target_crypto_init_params();
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08005320 hash_find((unsigned char *) image_addr, image_size, (unsigned char *)&digest, auth_algo);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005321
5322 save_kernel_hash_cmd(digest);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005323 dprintf(INFO, "aboot_save_boot_hash_mmc: imagesize_actual size %d bytes.\n", (int) image_size);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005324
5325 return 0;
5326}
5327
Mayank Grover351a75e2017-05-30 20:06:08 +05305328
Brian Swetland9c4c0752009-01-25 16:23:50 -08005329APP_START(aboot)
5330 .init = aboot_init,
5331APP_END