Merge "msm_shared: board: Add support for pmic info api"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index adeca41..a4aab73 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -104,6 +104,8 @@
 /* Assuming unauthorized kernel image by default */
 static int auth_kernel_img = 0;
 
+static uint32_t app_dev_tree = 0;
+
 static device_info device = {DEVICE_MAGIC, 0, 0};
 
 static struct udc_device surf_udc_device = {
@@ -412,7 +414,6 @@
 		dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
 		ASSERT(0);
 	}
-
 	dprintf(INFO, "Updating device tree: done\n");
 #else
 	/* Generating the Atags */
@@ -453,6 +454,7 @@
 	unsigned offset = 0;
 	unsigned long long ptn = 0;
 	const char *cmdline;
+	void *tags;
 	int index = INVALID_PTN;
 
 	unsigned char *image_addr = 0;
@@ -594,6 +596,16 @@
 
 			/* Read device device tree in the "tags_add */
 			memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry_ptr->offset, dt_entry_ptr->size);
+		} else {
+				/*
+				 * Look for appended device tree if DTB is not found in boot image
+				 * If found load the kernel & boot up
+				 */
+				app_dev_tree = dev_tree_appended((void*) hdr->kernel_addr);
+				if (!app_dev_tree) {
+					dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
+					return -1;
+				}
 		}
 		#endif
 		/* Make sure everything from scratch address is read before next step!*/
@@ -676,6 +688,16 @@
 				dprintf(CRITICAL, "ERROR: Cannot read device tree\n");
 				return -1;
 			}
+		} else {
+				/*
+				 * Look for appended device tree if DTB is not found in boot image
+				 * If found load the kernel & boot up
+				 */
+				app_dev_tree = dev_tree_appended((void*) hdr->kernel_addr);
+				if (!app_dev_tree) {
+					dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
+					return -1;
+				}
 		}
 		#endif
 	}
@@ -688,7 +710,17 @@
 		cmdline = DEFAULT_CMDLINE;
 	}
 
-	boot_linux((void *)hdr->kernel_addr, (unsigned *) hdr->tags_addr,
+	/*
+	 * If appended dev tree is found, update the atags with
+	 * memory address to the DTB appended location on RAM.
+	 * Else update with the atags address in the kernel header
+	 */
+	if (app_dev_tree)
+		tags = (void *)app_dev_tree;
+	else
+		tags = (void *)hdr->tags_addr;
+
+	boot_linux((void *)hdr->kernel_addr, (unsigned *)tags,
 		   (const char *)cmdline, board_machtype(),
 		   (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
 
@@ -1134,6 +1166,17 @@
 		memmove((void*) hdr->tags_addr,
 				boot_image_start + dt_image_offset +  dt_entry_ptr->offset,
 				dt_entry_ptr->size);
+	} else {
+		/*
+		 * Look for appended device tree if DTB is not found in boot image
+		 * If found load the kernel & boot up
+		 */
+		memmove((void*) hdr->kernel_addr, boot_image_start + page_size, hdr->kernel_size);
+		app_dev_tree = dev_tree_appended((void*) hdr->kernel_addr);
+		if (!app_dev_tree) {
+			dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
+			return -1;
+		}
 	}
 
 	/* Everything looks fine. Return success. */
@@ -1147,6 +1190,7 @@
 	unsigned ramdisk_actual;
 	struct boot_img_hdr *hdr;
 	char *ptr = ((char*) data);
+	void *tags;
 
 	if (sz < sizeof(hdr)) {
 		fastboot_fail("invalid bootimage header");
@@ -1192,7 +1236,17 @@
 	memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
 	memmove((void*) hdr->kernel_addr, ptr + page_size, hdr->kernel_size);
 
-	boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
+	/*
+	 * If appended dev tree is found, update the atags with
+	 * memory address to the DTB appended location on RAM.
+	 * Else update with the atags address in the kernel header
+	 */
+	if (app_dev_tree)
+		tags = (void *)app_dev_tree;
+	else
+		tags = (void *)hdr->tags_addr;
+
+	boot_linux((void*) hdr->kernel_addr, (void*) tags,
 		   (const char*) hdr->cmdline, board_machtype(),
 		   (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
 }
diff --git a/platform/msm8226/acpuclock.c b/platform/msm8226/acpuclock.c
index f1b3d41..df4c7f6 100644
--- a/platform/msm8226/acpuclock.c
+++ b/platform/msm8226/acpuclock.c
@@ -175,3 +175,7 @@
 	}
 }
 
+void clock_config_ce(uint8_t instance)
+{
+}
+
diff --git a/platform/msm8226/include/platform/clock.h b/platform/msm8226/include/platform/clock.h
index b549dd1..118428a 100644
--- a/platform/msm8226/include/platform/clock.h
+++ b/platform/msm8226/include/platform/clock.h
@@ -40,5 +40,6 @@
 void clock_config_mmc(uint32_t interface, uint32_t freq);
 void clock_config_uart_dm(uint8_t id);
 void hsusb_clock_init(void);
+void clock_config_ce(uint8_t instance);
 
 #endif
diff --git a/platform/msm8226/include/platform/iomap.h b/platform/msm8226/include/platform/iomap.h
index 5a49bb9..9519882 100644
--- a/platform/msm8226/include/platform/iomap.h
+++ b/platform/msm8226/include/platform/iomap.h
@@ -38,6 +38,9 @@
 
 #define APPS_SS_BASE                0xF9000000
 
+#define SYSTEM_IMEM_BASE            0xFE800000
+#define RESTART_REASON_ADDR         (SYSTEM_IMEM_BASE + 0x565C)
+
 #define MSM_GIC_DIST_BASE           APPS_SS_BASE
 #define MSM_GIC_CPU_BASE            (APPS_SS_BASE + 0x2000)
 #define APPS_APCS_QTMR_AC_BASE      (APPS_SS_BASE + 0x00020000)
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 04caeb1..6a06a12 100644
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -39,6 +39,28 @@
 extern int target_is_emmc_boot(void);
 extern uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset);
 
+/*
+ * Argument:     Start address of the kernel loaded in RAM
+ * Return Value: DTB address : If appended device tree is found
+ *               '0'         : Otherwise
+ */
+uint32_t dev_tree_appended(void *kernel)
+{
+	uint32_t app_dtb_offset = 0;
+	uint32_t dtb_magic = 0;
+	uint32_t dtb = 0;
+
+	memcpy((void*) &app_dtb_offset, (void*) (kernel + DTB_OFFSET), sizeof(uint32_t));
+	memcpy((void*) &dtb_magic, (void*) (kernel + app_dtb_offset), sizeof(uint32_t));
+
+	if (dtb_magic == DTB_MAGIC) {
+		dprintf(INFO, "Found Appeneded Flattened Device tree\n");
+		dtb = (uint32_t) (kernel + app_dtb_offset);
+	}
+
+	return dtb;
+}
+
 /* Function to return the pointer to the start of the correct device tree
  *  based on the platform data.
  */
diff --git a/platform/msm_shared/include/dev_tree.h b/platform/msm_shared/include/dev_tree.h
index 5c58b38..389ab49 100644
--- a/platform/msm_shared/include/dev_tree.h
+++ b/platform/msm_shared/include/dev_tree.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -37,6 +37,9 @@
 #define DEV_TREE_VERSION        1
 #define DEV_TREE_HEADER_SIZE    12
 
+#define DTB_MAGIC               0xedfe0dd0
+#define DTB_OFFSET              0x2C
+
 struct dt_entry
 {
 	uint32_t platform_id;
@@ -62,5 +65,5 @@
 struct dt_entry * dev_tree_get_entry_ptr(struct dt_table *);
 int update_device_tree(void *, const char *, void *, unsigned);
 int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint32_t size, uint32_t addr);
-
+uint32_t dev_tree_appended(void *);
 #endif
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index e0cbb50..1045240 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -100,6 +100,11 @@
 			$(LOCAL_DIR)/spmi.o \
 			$(LOCAL_DIR)/bam.o \
 			$(LOCAL_DIR)/qpic_nand.o \
+            $(LOCAL_DIR)/certificate.o \
+            $(LOCAL_DIR)/image_verify.o \
+            $(LOCAL_DIR)/crypto_hash.o \
+            $(LOCAL_DIR)/crypto5_eng.o \
+            $(LOCAL_DIR)/crypto5_wrapper.o \
 			$(LOCAL_DIR)/dev_tree.o
 endif
 
diff --git a/project/msm8226.mk b/project/msm8226.mk
index 0ba5aaa..a9d45b2 100644
--- a/project/msm8226.mk
+++ b/project/msm8226.mk
@@ -13,4 +13,4 @@
 #DEFINES += WITH_DEBUG_FBCON=1
 DEFINES += DEVICE_TREE=1
 #DEFINES += MMC_BOOT_BAM=1
-#DEFINES += CRYPTO_BAM=1
+DEFINES += CRYPTO_BAM=1
diff --git a/target/msm8226/init.c b/target/msm8226/init.c
index a1c322a..a3b0fff 100644
--- a/target/msm8226/init.c
+++ b/target/msm8226/init.c
@@ -33,14 +33,28 @@
 #include <platform.h>
 #include <uart_dm.h>
 #include <mmc.h>
+#include <platform/gpio.h>
 #include <spmi.h>
 #include <board.h>
 #include <smem.h>
 #include <baseband.h>
+#include <dev/keys.h>
 #include <pm8x41.h>
+#include <crypto5_wrapper.h>
 
-#define PMIC_ARB_CHANNEL_NUM    0
-#define PMIC_ARB_OWNER_ID       0
+extern  bool target_use_signed_kernel(void);
+
+#define PMIC_ARB_CHANNEL_NUM               0
+#define PMIC_ARB_OWNER_ID                  0
+
+#define CRYPTO_ENGINE_INSTANCE             1
+#define CRYPTO_ENGINE_EE                   1
+#define CRYPTO_ENGINE_FIFO_SIZE            64
+#define CRYPTO_ENGINE_READ_PIPE            3
+#define CRYPTO_ENGINE_WRITE_PIPE           2
+#define CRYPTO_ENGINE_CMD_ARRAY_SIZE       20
+
+#define TLMM_VOL_UP_BTN_GPIO    106
 
 static uint32_t mmc_sdc_base[] =
 	{ MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE };
@@ -52,8 +66,59 @@
 #endif
 }
 
+/* Return 1 if vol_up pressed */
+static int target_volume_up()
+{
+	uint8_t status = 0;
+
+	gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
+
+	/* Get status of GPIO */
+	status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
+
+	/* Active low signal. */
+	return !status;
+}
+
+/* Return 1 if vol_down pressed */
+uint32_t target_volume_down()
+{
+	/* Volume down button tied in with PMIC RESIN. */
+	return pm8x41_resin_status();
+}
+
 static void target_keystatus()
 {
+	keys_init();
+
+	if(target_volume_down())
+		keys_post_event(KEY_VOLUMEDOWN, 1);
+
+	if(target_volume_up())
+		keys_post_event(KEY_VOLUMEUP, 1);
+}
+
+/* Set up params for h/w CRYPTO_ENGINE. */
+void target_crypto_init_params()
+{
+	struct crypto_init_params ce_params;
+
+	/* Set up base addresses and instance. */
+	ce_params.crypto_instance  = CRYPTO_ENGINE_INSTANCE;
+	ce_params.crypto_base      = MSM_CE1_BASE;
+	ce_params.bam_base         = MSM_CE1_BAM_BASE;
+
+	/* Set up BAM config. */
+	ce_params.bam_ee           = CRYPTO_ENGINE_EE;
+	ce_params.pipes.read_pipe  = CRYPTO_ENGINE_READ_PIPE;
+	ce_params.pipes.write_pipe = CRYPTO_ENGINE_WRITE_PIPE;
+
+	/* Assign buffer sizes. */
+	ce_params.num_ce           = CRYPTO_ENGINE_CMD_ARRAY_SIZE;
+	ce_params.read_fifo_size   = CRYPTO_ENGINE_FIFO_SIZE;
+	ce_params.write_fifo_size  = CRYPTO_ENGINE_FIFO_SIZE;
+
+	crypto_init_params(&ce_params);
 }
 
 void target_init(void)
@@ -81,6 +146,9 @@
 			ASSERT(0);
 		}
 	}
+
+	if (target_use_signed_kernel())
+		target_crypto_init_params();
 }
 
 /* Do any target specific intialization needed before entering fastboot mode */
@@ -141,6 +209,37 @@
 	}
 }
 
+unsigned check_reboot_mode(void)
+{
+	uint32_t restart_reason = 0;
+
+	/* Read reboot reason and scrub it */
+	restart_reason = readl(RESTART_REASON_ADDR);
+	writel(0x00, RESTART_REASON_ADDR);
+
+	return restart_reason;
+}
+
+void reboot_device(unsigned reboot_reason)
+{
+	writel(reboot_reason, RESTART_REASON_ADDR);
+
+	/* Configure PMIC for warm reset */
+	pm8x41_reset_configure(PON_PSHOLD_WARM_RESET);
+
+	/* Drop PS_HOLD for MSM */
+	writel(0x00, MPM2_MPM_PS_HOLD);
+
+	mdelay(5000);
+
+	dprintf(CRITICAL, "Rebooting failed\n");
+}
+
+crypto_engine_type board_ce_type(void)
+{
+	return CRYPTO_ENGINE_TYPE_HW;
+}
+
 unsigned board_machtype(void)
 {
 }