aboot: Store unlock and rooted flag on NAND and eMMC.
-- Add 'fastboot oem unlock' command.
-- Add support to store ulock and rooted flags on disk.
-- Add support to reset rooted flag on request from recovery partition.
Change-Id: I9dc5c13f69a266ff6c81cc7157b43a975fbbf9e0
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 312b278..f2d1169 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -55,8 +55,9 @@
#include "fastboot.h"
#include "sparse_format.h"
#include "mmc.h"
+#include "devinfo.h"
-#include "scm_decrypt.h"
+#include "scm.h"
#define EXPAND(NAME) #NAME
#define TARGET(NAME) EXPAND(NAME)
@@ -84,6 +85,8 @@
/* Assuming unauthorized kernel image by default */
static int auth_kernel_img = 0;
+static device_info device = {DEVICE_MAGIC, 0, 0};
+
static struct udc_device surf_udc_device = {
.vendor_id = 0x18d1,
.product_id = 0xD00D,
@@ -353,7 +356,7 @@
}
/* Authenticate Kernel */
- if(target_use_signed_kernel())
+ if(target_use_signed_kernel() && (!device.is_unlocked) && (!device.is_rooted))
{
image_addr = (unsigned char *)target_get_scratch_address();
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
@@ -361,6 +364,10 @@
imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
offset = 0;
+
+ /* Assuming device rooted at this time */
+ device.is_rooted = 1;
+
/* Read image without signature */
if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
{
@@ -380,11 +387,26 @@
(unsigned char *)(image_addr + imagesize_actual),
imagesize_actual,
CRYPTO_AUTH_ALG_SHA256);
+
+ if(auth_kernel_img)
+ {
+ /* Authorized kernel */
+ device.is_rooted = 0;
+ }
}
/* Move kernel and ramdisk to correct address */
memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
+
+ /* Make sure everything from scratch address is read before next step!*/
+ if(device.is_rooted)
+ {
+ write_device_info_mmc(&device);
+ #ifdef TZ_TAMPER_FUSE
+ set_tamper_fuse_cmd();
+ #endif
+ }
}
else
{
@@ -479,7 +501,6 @@
dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
return -1;
}
- offset += page_size;
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
@@ -492,7 +513,7 @@
}
/* Authenticate Kernel */
- if(target_use_signed_kernel())
+ if(target_use_signed_kernel() && (!device.is_unlocked) && (!device.is_rooted))
{
image_addr = (unsigned char *)target_get_scratch_address();
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
@@ -500,6 +521,10 @@
imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
offset = 0;
+
+ /* Assuming device rooted at this time */
+ device.is_rooted = 1;
+
/* Read image without signature */
if (flash_read(ptn, offset, (void *)image_addr, imagesize_actual))
{
@@ -521,14 +546,28 @@
(unsigned char *)(image_addr + imagesize_actual),
imagesize_actual,
CRYPTO_AUTH_ALG_SHA256);
+
+ if(auth_kernel_img)
+ {
+ /* Authorized kernel */
+ device.is_rooted = 0;
+ }
}
/* Move kernel and ramdisk to correct address */
memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
+
+ /* Make sure everything from scratch address is read before next step!*/
+ if(device.is_rooted)
+ {
+ write_device_info_flash(&device);
+ }
}
else
{
+ offset = page_size;
+
n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
if (flash_read(ptn, offset, (void *)hdr->kernel_addr, n)) {
dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
@@ -566,12 +605,176 @@
return 0;
}
+unsigned char info_buf[4096];
+void write_device_info_mmc(device_info *dev)
+{
+ struct device_info *info = (void*) info_buf;
+ unsigned long long ptn = 0;
+ unsigned long long size;
+ int index = INVALID_PTN;
+
+ index = partition_get_index("aboot");
+ ptn = partition_get_offset(index);
+ if(ptn == 0)
+ {
+ return;
+ }
+
+ size = partition_get_size(index);
+
+ memcpy(info, dev, sizeof(device_info));
+
+ if(mmc_write((ptn + size - 512), 512, (void *)info_buf))
+ {
+ dprintf(CRITICAL, "ERROR: Cannot write device info\n");
+ return;
+ }
+}
+
+void read_device_info_mmc(device_info *dev)
+{
+ struct device_info *info = (void*) info_buf;
+ unsigned long long ptn = 0;
+ unsigned long long size;
+ int index = INVALID_PTN;
+
+ index = partition_get_index("aboot");
+ ptn = partition_get_offset(index);
+ if(ptn == 0)
+ {
+ return;
+ }
+
+ size = partition_get_size(index);
+
+ if(mmc_read((ptn + size - 512), (void *)info_buf, 512))
+ {
+ dprintf(CRITICAL, "ERROR: Cannot read device info\n");
+ return;
+ }
+
+ if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
+ {
+ memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
+ info->is_unlocked = 0;
+ info->is_rooted = 0;
+
+ write_device_info_mmc(info);
+ }
+ memcpy(dev, info, sizeof(device_info));
+}
+
+void write_device_info_flash(device_info *dev)
+{
+ struct device_info *info = (void *) info_buf;
+ struct ptentry *ptn;
+ struct ptable *ptable;
+
+ ptable = flash_get_ptable();
+ if (ptable == NULL)
+ {
+ dprintf(CRITICAL, "ERROR: Partition table not found\n");
+ return;
+ }
+
+ ptn = ptable_find(ptable, "devinfo");
+ if (ptn == NULL)
+ {
+ dprintf(CRITICAL, "ERROR: No boot partition found\n");
+ return;
+ }
+
+ memcpy(info, dev, sizeof(device_info));
+
+ if (flash_write(ptn, 0, (void *)info_buf, page_size))
+ {
+ dprintf(CRITICAL, "ERROR: Cannot write device info\n");
+ return;
+ }
+}
+
+void read_device_info_flash(device_info *dev)
+{
+ struct device_info *info = (void*) info_buf;
+ struct ptentry *ptn;
+ struct ptable *ptable;
+
+ ptable = flash_get_ptable();
+ if (ptable == NULL)
+ {
+ dprintf(CRITICAL, "ERROR: Partition table not found\n");
+ return;
+ }
+
+ ptn = ptable_find(ptable, "devinfo");
+ if (ptn == NULL)
+ {
+ dprintf(CRITICAL, "ERROR: No boot partition found\n");
+ return;
+ }
+
+ if (flash_read(ptn, 0, (void *)info_buf, page_size))
+ {
+ dprintf(CRITICAL, "ERROR: Cannot write device info\n");
+ return;
+ }
+
+ if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
+ {
+ while(1);
+ memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
+ info->is_unlocked = 0;
+ info->is_rooted = 0;
+ write_device_info_flash(info);
+ }
+ memcpy(dev, info, sizeof(device_info));
+}
+
+void write_device_info(device_info *dev)
+{
+ if(target_is_emmc_boot())
+ {
+ write_device_info_mmc(dev);
+ }
+ else
+ {
+ write_device_info_flash(dev);
+ }
+}
+
+void read_device_info(device_info *dev)
+{
+ if(target_is_emmc_boot())
+ {
+ read_device_info_mmc(dev);
+ }
+ else
+ {
+ read_device_info_flash(dev);
+ }
+}
+
+void reset_device_info()
+{
+ dprintf(ALWAYS, "reset_device_info called.");
+ device.is_rooted = 0;
+ write_device_info(&device);
+}
+
+void set_device_root()
+{
+ dprintf(ALWAYS, "set_device_root called.");
+ device.is_rooted = 1;
+ write_device_info(&device);
+}
+
void cmd_boot(const char *arg, void *data, unsigned sz)
{
unsigned kernel_actual;
unsigned ramdisk_actual;
static struct boot_img_hdr hdr;
char *ptr = ((char*) data);
+ unsigned image_actual;
if (sz < sizeof(hdr)) {
fastboot_fail("invalid bootimage header");
@@ -590,8 +793,12 @@
kernel_actual = ROUND_TO_PAGE(hdr.kernel_size, page_mask);
ramdisk_actual = ROUND_TO_PAGE(hdr.ramdisk_size, page_mask);
+ image_actual = page_size + kernel_actual + ramdisk_actual;
- if (page_size + kernel_actual + ramdisk_actual < sz) {
+ if(target_use_signed_kernel())
+ image_actual += page_size;
+
+ if (image_actual > sz) {
fastboot_fail("incomplete bootimage");
return;
}
@@ -699,8 +906,6 @@
return;
}
-
-
void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
{
unsigned int chunk;
@@ -911,6 +1116,16 @@
reboot_device(FASTBOOT_MODE);
}
+void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
+{
+ if(!device.is_unlocked)
+ {
+ device.is_unlocked = 1;
+ write_device_info(&device);
+ }
+ fastboot_okay("");
+}
+
void splash_screen ()
{
struct ptentry *ptn;
@@ -959,6 +1174,18 @@
page_mask = page_size - 1;
}
+ if(target_use_signed_kernel())
+ {
+ read_device_info(&device);
+
+ if((device.is_unlocked) || (device.is_rooted))
+ {
+ #ifdef TZ_TAMPER_FUSE
+ set_tamper_fuse_cmd();
+ #endif
+ }
+ }
+
target_serialno((unsigned char *) sn_buf);
dprintf(SPEW,"serial number: %s\n",sn_buf);
surf_udc_device.serialno = sn_buf;
@@ -1008,7 +1235,7 @@
fastboot:
- target_fastboot_init();
+ target_fastboot_init();
if(!usb_init)
udc_init(&surf_udc_device);
@@ -1029,8 +1256,11 @@
fastboot_register("continue", cmd_continue);
fastboot_register("reboot", cmd_reboot);
fastboot_register("reboot-bootloader", cmd_reboot_bootloader);
+ fastboot_register("oem unlock", cmd_oem_unlock);
fastboot_publish("product", TARGET(BOARD));
fastboot_publish("kernel", "lk");
+ fastboot_publish("root-flag", device.is_rooted);
+ fastboot_publish("unlock-flag", device.is_unlocked);
partition_dump();
sz = target_get_max_flash_size();
fastboot_init(target_get_scratch_address(), sz);
diff --git a/app/aboot/devinfo.h b/app/aboot/devinfo.h
new file mode 100644
index 0000000..51cc9c7
--- /dev/null
+++ b/app/aboot/devinfo.h
@@ -0,0 +1,45 @@
+/*
+ * * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEVINFO_H_
+#define _DEVINFO_H_
+
+typedef struct device_info device_info;
+
+#define DEVICE_MAGIC "ANDROID-BOOT!"
+#define DEVICE_MAGIC_SIZE 13
+
+struct device_info
+{
+ unsigned char magic[DEVICE_MAGIC_SIZE];
+ bool is_unlocked;
+ bool is_rooted;
+};
+
+#endif
diff --git a/app/aboot/recovery.c b/app/aboot/recovery.c
index 2ff6804..898ccb6 100644
--- a/app/aboot/recovery.c
+++ b/app/aboot/recovery.c
@@ -53,6 +53,8 @@
static char buf[4096];
unsigned boot_into_recovery = 0;
+extern void reset_device_info();
+extern void set_device_root();
int get_recovery_message(struct recovery_message *out)
{
@@ -447,12 +449,20 @@
dprintf(INFO,"radio update failed\n");
strcpy(msg.status, "failed-update");
}
+ boot_into_recovery = 1; // Boot in recovery mode
+ }
+ if (!strcmp("reset-device-info",msg.command))
+ {
+ reset_device_info();
+ }
+ if (!strcmp("root-detect",msg.command))
+ {
+ set_device_root();
}
else
return 0; // do nothing
strcpy(msg.command, ""); // clearing recovery command
emmc_set_recovery_msg(&msg); // send recovery message
- boot_into_recovery = 1; // Boot in recovery mode
return 0;
}
diff --git a/platform/msm8x60/rules.mk b/platform/msm8x60/rules.mk
index a5c7f64..42a12cc 100755
--- a/platform/msm8x60/rules.mk
+++ b/platform/msm8x60/rules.mk
@@ -10,7 +10,7 @@
DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0 \
MMC_SLOT=$(MMC_SLOT) MDP4=1 \
- SSD_ENABLE
+ SSD_ENABLE TZ_TAMPER_FUSE
DEFINES += QT_8660_KEYPAD_HW_BUG=1
diff --git a/platform/msm_shared/include/scm.h b/platform/msm_shared/include/scm.h
new file mode 100644
index 0000000..456cf46
--- /dev/null
+++ b/platform/msm_shared/include/scm.h
@@ -0,0 +1,125 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SCM_H__
+#define __SCM_H__
+
+/* 8 Byte SSD magic number (LE) */
+#define SSD_HEADER_MAGIC_0 0x73737A74
+#define SSD_HEADER_MAGIC_1 0x676D6964
+#define SSD_HEADER_MAGIC_SIZE 8
+#define SSD_HEADER_XML_SIZE 2048
+
+typedef unsigned int uint32;
+
+typedef struct
+{
+ uint32 len;
+ uint32 buf_offset;
+ uint32 resp_hdr_offset;
+ uint32 id;
+} scm_command;
+
+typedef struct
+{
+ uint32 len;
+ uint32 buf_offset;
+ uint32 is_complete;
+} scm_response;
+
+typedef struct
+{
+ scm_command common_req;
+ uint32* img_ptr;
+ uint32* img_len_ptr;
+} decrypt_img_req;
+
+#define SYSCALL_CREATE_CMD_ID(s, f) \
+ ((uint32)(((s & 0x3ff) << 10) | (f & 0x3ff)))
+
+#define SCM_SVC_SSD 7
+#define SSD_DECRYPT_IMG_ID SYSCALL_CREATE_CMD_ID(SCM_SVC_SSD, 0x01)
+
+void setup_decrypt_cmd ( decrypt_img_req* dec_cmd,
+ uint32** img_ptr,
+ uint32* img_len_ptr);
+static uint32 smc(uint32 cmd_addr);
+int decrypt_img_scm(uint32** img_ptr, uint32* img_len_ptr);
+
+#define SCM_SVC_FUSE 0x08
+#define SCM_BLOW_SW_FUSE_ID 0x01
+#define SCM_IS_SW_FUSE_BLOWN_ID 0x02
+
+#define HLOS_IMG_TAMPER_FUSE 0
+void set_tamper_fuse_cmd();
+
+/**
+ * struct scm_command - one SCM command buffer
+ * @len: total available memory for command and response
+ * @buf_offset: start of command buffer
+ * @resp_hdr_offset: start of response buffer
+ * @id: command to be executed
+ * @buf: buffer returned from scm_get_command_buffer()
+ *
+ * An SCM command is layed out in memory as follows:
+ *
+ * ------------------- <--- struct scm_command
+ * | command header |
+ * ------------------- <--- scm_get_command_buffer()
+ * | command buffer |
+ * ------------------- <--- struct scm_response and
+ * | response header | scm_command_to_response()
+ * ------------------- <--- scm_get_response_buffer()
+ * | response buffer |
+ * -------------------
+ *
+ * There can be arbitrary padding between the headers and buffers so
+ * you should always use the appropriate scm_get_*_buffer() routines
+ * to access the buffers in a safe manner.
+ */
+struct scm_command {
+ uint32_t len;
+ uint32_t buf_offset;
+ uint32_t resp_hdr_offset;
+ uint32_t id;
+ uint32_t buf[0];
+};
+
+/**
+ * struct scm_response - one SCM response buffer
+ * @len: total available memory for response
+ * @buf_offset: start of response data relative to start of scm_response
+ * @is_complete: indicates if the command has finished processing
+ */
+struct scm_response {
+ uint32_t len;
+ uint32_t buf_offset;
+ uint32_t is_complete;
+};
+
+#endif
diff --git a/platform/msm_shared/include/scm_decrypt.h b/platform/msm_shared/include/scm_decrypt.h
deleted file mode 100644
index 4740759..0000000
--- a/platform/msm_shared/include/scm_decrypt.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Code Aurora Forum, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-
-/* 8 Byte SSD magic number (LE) */
-#define SSD_HEADER_MAGIC_0 0x73737A74
-#define SSD_HEADER_MAGIC_1 0x676D6964
-#define SSD_HEADER_MAGIC_SIZE 8
-#define SSD_HEADER_XML_SIZE 2048
-
-typedef unsigned int uint32;
-
-typedef struct
-{
- uint32 len;
- uint32 buf_offset;
- uint32 resp_hdr_offset;
- uint32 id;
-} scm_command;
-
-typedef struct
-{
- uint32 len;
- uint32 buf_offset;
- uint32 is_complete;
-} scm_response;
-
-typedef struct
-{
- scm_command common_req;
- uint32* img_ptr;
- uint32* img_len_ptr;
-} decrypt_img_req;
-
-#define SYSCALL_CREATE_CMD_ID(s, f) \
- ((uint32)(((s & 0x3ff) << 10) | (f & 0x3ff)))
-
-#define SCM_SVC_SSD 7
-#define SSD_DECRYPT_IMG_ID SYSCALL_CREATE_CMD_ID(SCM_SVC_SSD, 0x01)
-
-void setup_decrypt_cmd ( decrypt_img_req* dec_cmd,
- uint32** img_ptr,
- uint32* img_len_ptr);
-static uint32 smc(uint32 cmd_addr);
-int decrypt_img_scm(uint32** img_ptr, uint32* img_len_ptr);
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 7887a8f..f2edb0e 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -24,7 +24,7 @@
$(LOCAL_DIR)/uart_dm.o \
$(LOCAL_DIR)/crypto_eng.o \
$(LOCAL_DIR)/crypto_hash.o \
- $(LOCAL_DIR)/scm_decrypt.o \
+ $(LOCAL_DIR)/scm.o \
$(LOCAL_DIR)/lcdc.o \
$(LOCAL_DIR)/mddi.o \
$(LOCAL_DIR)/qgic.o \
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
new file mode 100644
index 0000000..5838afd
--- /dev/null
+++ b/platform/msm_shared/scm.c
@@ -0,0 +1,251 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include "scm.h"
+
+#pragma GCC optimize ("O0")
+
+/* From Linux Kernel asm/system.h */
+#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+#ifndef offsetof
+# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+/**
+ * alloc_scm_command() - Allocate an SCM command
+ * @cmd_size: size of the command buffer
+ * @resp_size: size of the response buffer
+ *
+ * Allocate an SCM command, including enough room for the command
+ * and response headers as well as the command and response buffers.
+ *
+ * Returns a valid &scm_command on success or %NULL if the allocation fails.
+ */
+static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
+{
+ struct scm_command *cmd;
+ size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
+ resp_size;
+
+ cmd = malloc(len);
+ if (cmd)
+ {
+ cmd->len = len;
+ cmd->buf_offset = offsetof(struct scm_command, buf);
+ cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
+ }
+ return cmd;
+}
+
+/**
+ * free_scm_command() - Free an SCM command
+ * @cmd: command to free
+ *
+ * Free an SCM command.
+ */
+static inline void free_scm_command(struct scm_command *cmd)
+{
+ free(cmd);
+}
+
+/**
+ * scm_command_to_response() - Get a pointer to a scm_response
+ * @cmd: command
+ *
+ * Returns a pointer to a response for a command.
+ */
+static inline struct scm_response *scm_command_to_response(
+ const struct scm_command *cmd)
+{
+ return (void *)cmd + cmd->resp_hdr_offset;
+}
+
+/**
+ * scm_get_command_buffer() - Get a pointer to a command buffer
+ * @cmd: command
+ *
+ * Returns a pointer to the command buffer of a command.
+ */
+static inline void *scm_get_command_buffer(const struct scm_command *cmd)
+{
+ return (void *)cmd->buf;
+}
+
+/**
+ * scm_get_response_buffer() - Get a pointer to a response buffer
+ * @rsp: response
+ *
+ * Returns a pointer to a response buffer of a response.
+ */
+static inline void *scm_get_response_buffer(const struct scm_response *rsp)
+{
+ return (void *)rsp + rsp->buf_offset;
+}
+
+static uint32_t smc(uint32_t cmd_addr)
+{
+ uint32_t context_id;
+ register uint32_t r0 __asm__("r0") = 1;
+ register uint32_t r1 __asm__("r1") = (uint32_t)&context_id;
+ register uint32_t r2 __asm__("r2") = cmd_addr;
+ __asm__(
+ "1:smc #0 @ switch to secure world\n"
+ "cmp r0, #1 \n"
+ "beq 1b \n"
+ : "=r" (r0)
+ : "r" (r0), "r" (r1), "r" (r2)
+ : "r3", "cc");
+ return r0;
+}
+
+/**
+ * scm_call() - Send an SCM command
+ * @svc_id: service identifier
+ * @cmd_id: command identifier
+ * @cmd_buf: command buffer
+ * @cmd_len: length of the command buffer
+ * @resp_buf: response buffer
+ * @resp_len: length of the response buffer
+ *
+ * Sends a command to the SCM and waits for the command to finish processing.
+ */
+int scm_call(uint32_t svc_id, uint32_t cmd_id, const void *cmd_buf, size_t cmd_len,
+ void *resp_buf, size_t resp_len)
+{
+ int ret;
+ struct scm_command *cmd;
+ struct scm_response *rsp;
+
+ cmd = alloc_scm_command(cmd_len, resp_len);
+ if (!cmd)
+ return ERR_NO_MEMORY;
+
+ cmd->id = (svc_id << 10) | cmd_id;
+ if (cmd_buf)
+ memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
+
+ ret = smc((uint32_t)cmd);
+ if (ret)
+ goto out;
+
+ if(resp_len)
+ {
+ rsp = scm_command_to_response(cmd);
+
+ while (!rsp->is_complete);
+
+ if (resp_buf)
+ memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
+ }
+out:
+ free_scm_command(cmd);
+ return ret;
+}
+
+/* SCM Decrypt Command */
+void setup_decrypt_cmd ( decrypt_img_req* dec_cmd,
+ uint32_t** img_ptr,
+ uint32_t* img_len_ptr)
+{
+ dec_cmd->common_req.len = sizeof(decrypt_img_req);
+ dec_cmd->common_req.buf_offset = sizeof(scm_command);
+ dec_cmd->common_req.resp_hdr_offset = 0;
+ dec_cmd->common_req.id = SSD_DECRYPT_IMG_ID;
+
+ dec_cmd->img_ptr = img_ptr;
+ dec_cmd->img_len_ptr = img_len_ptr;
+}
+
+int decrypt_img_scm(uint32_t** img_ptr, uint32_t* img_len_ptr)
+{
+ int ret = 0;
+ decrypt_img_req *decrypt_cmd;
+
+ /* allocate memory for the command structure */
+ /* NEEDS TO BE CONTIGUOUS MEMORY */
+ decrypt_cmd = malloc(sizeof(decrypt_img_req));
+
+ /* setup the command for decryption */
+ setup_decrypt_cmd(decrypt_cmd, img_ptr, img_len_ptr);
+
+ ret = smc(decrypt_cmd);
+ free(decrypt_cmd);
+ return ret;
+}
+
+void set_tamper_fuse_cmd()
+{
+ uint32_t svc_id;
+ uint32_t cmd_id;
+ void *cmd_buf;
+ size_t cmd_len;
+ void *resp_buf = NULL;
+ size_t resp_len = 0;
+
+ uint32_t fuse_id = HLOS_IMG_TAMPER_FUSE;
+ cmd_buf = (void *)&fuse_id;
+ cmd_len = sizeof(fuse_id);
+
+ /*no response*/
+ resp_buf = NULL;
+ resp_len = 0;
+
+ svc_id = SCM_SVC_FUSE;
+ cmd_id = SCM_BLOW_SW_FUSE_ID;
+
+ scm_call(svc_id, cmd_id, cmd_buf, cmd_len, resp_buf, resp_len);
+ return;
+}
+
+uint8_t get_tamper_fuse_cmd()
+{
+ uint32_t svc_id;
+ uint32_t cmd_id;
+ void *cmd_buf;
+ size_t cmd_len;
+ size_t resp_len = 0;
+ uint8_t resp_buf;
+
+ uint32_t fuse_id = HLOS_IMG_TAMPER_FUSE;
+ cmd_buf = (void *)&fuse_id;
+ cmd_len = sizeof(fuse_id);
+
+ /*response*/
+ resp_len = sizeof(resp_buf);
+
+ svc_id = SCM_SVC_FUSE;
+ cmd_id = SCM_IS_SW_FUSE_BLOWN_ID;
+
+ scm_call(svc_id, cmd_id, cmd_buf, cmd_len, &resp_buf, resp_len);
+ return resp_buf;
+}
+
diff --git a/platform/msm_shared/scm_decrypt.c b/platform/msm_shared/scm_decrypt.c
deleted file mode 100644
index df1b399..0000000
--- a/platform/msm_shared/scm_decrypt.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Code Aurora Forum, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "scm_decrypt.h"
-
-#pragma GCC optimize ("O0")
-
-/* From Linux Kernel asm/system.h */
-#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
-
-void setup_decrypt_cmd ( decrypt_img_req* dec_cmd,
- uint32_t** img_ptr,
- uint32_t* img_len_ptr)
-{
- dec_cmd->common_req.len = sizeof(decrypt_img_req);
- dec_cmd->common_req.buf_offset = sizeof(scm_command);
- dec_cmd->common_req.resp_hdr_offset = 0;
- dec_cmd->common_req.id = SSD_DECRYPT_IMG_ID;
-
- dec_cmd->img_ptr = img_ptr;
- dec_cmd->img_len_ptr = img_len_ptr;
-}
-
-static uint32_t smc(uint32_t cmd_addr)
-{
- uint32_t context_id;
- register uint32_t r0 __asm__("r0") = 1;
- register uint32_t r1 __asm__("r1") = (uint32_t)&context_id;
- register uint32_t r2 __asm__("r2") = cmd_addr;
- __asm__(
- "1:smc #0 @ switch to secure world\n"
- "cmp r0, #1 \n"
- "beq 1b \n"
- : "=r" (r0)
- : "r" (r0), "r" (r1), "r" (r2)
- : "r3", "cc");
- return r0;
-}
-
-
-int decrypt_img_scm(uint32_t** img_ptr, uint32_t* img_len_ptr)
-{
- int ret = 0;
- decrypt_img_req *decrypt_cmd;
-
- /* allocate memory for the command structure */
- /* NEEDS TO BE CONTIGUOUS MEMORY */
- decrypt_cmd = malloc(sizeof(decrypt_img_req));
-
- /* setup the command for decryption */
- setup_decrypt_cmd(decrypt_cmd, img_ptr, img_len_ptr);
-
- ret = smc(decrypt_cmd);
- free(decrypt_cmd);
- return ret;
-}
-
diff --git a/target/msm7630_surf/init.c b/target/msm7630_surf/init.c
index c89c252..675653b 100644
--- a/target/msm7630_surf/init.c
+++ b/target/msm7630_surf/init.c
@@ -87,6 +87,11 @@
},
{
.start = DIFF_START_ADDR,
+ .length = 1 /* In MB */,
+ .name = "devinfo",
+ },
+ {
+ .start = DIFF_START_ADDR,
.length = VARIABLE_LENGTH,
.name = "userdata",
},
diff --git a/target/msm8660_surf/init.c b/target/msm8660_surf/init.c
index 3629e7a..f0c49f6 100755
--- a/target/msm8660_surf/init.c
+++ b/target/msm8660_surf/init.c
@@ -447,3 +447,11 @@
{
return uart_gsbi_id;
}
+
+int emmc_recovery_init(void)
+{
+ int rc;
+ rc = _emmc_recovery_init();
+ return rc;
+}
+