platform: msm_shared: Fix scm init and scm_io_read
Make sure scm driver is initialized before any client calls into scm and
fix the return value of scm_io_read to return the value read from the
register instead of api success/failure values.
Change-Id: Ic43b9c8ec51876eec1c033ae1f2f71560ea7b9f7
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index df4b136..58cfc25 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -36,6 +36,7 @@
#include <image_verify.h>
#include <dload_util.h>
#include <platform/iomap.h>
+#include <board.h>
#include "scm.h"
#pragma GCC optimize ("O0")
@@ -56,9 +57,16 @@
/* SCM interface as per ARM spec present? */
bool scm_arm_support;
+static bool scm_initialized;
bool is_scm_armv8_support()
{
+ if (!scm_initialized)
+ {
+ scm_init();
+ scm_initialized = true;
+ }
+
return scm_arm_support;
}
@@ -96,6 +104,9 @@
{
int ret;
+ if (scm_initialized)
+ return;
+
ret = scm_arm_support_available(SCM_SVC_INFO, IS_CALL_AVAIL_CMD);
if (ret < 0)
@@ -308,7 +319,7 @@
secure_cfg.spare = 0;
scmcall_arg scm_arg = {0};
- if(!scm_arm_support)
+ if(!is_scm_armv8_support())
{
ret = scm_call(SVC_MEMORY_PROTECTION, IOMMU_SECURE_CFG, &secure_cfg, sizeof(secure_cfg),
NULL, 0);
@@ -348,7 +359,7 @@
*/
arch_clean_invalidate_cache_range((addr_t) *img_ptr, *img_len_ptr);
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
ret = scm_call(SCM_SVC_SSD, SSD_ENCRYPT_ID, &cmd, sizeof(cmd), NULL, 0);
}
@@ -380,7 +391,7 @@
int ret;
img_req cmd;
- if (scm_arm_support)
+ if (is_scm_armv8_support())
{
dprintf(INFO, "%s:SCM call is not supported\n",__func__);
return -1;
@@ -431,7 +442,7 @@
do
{
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
ret = scm_call(SCM_SVC_SSD,
SSD_PARSE_MD_ID,
@@ -515,7 +526,7 @@
decrypt_req.frag_len = *img_len_ptr;
decrypt_req.frag = *img_ptr;
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
ret = scm_call(SCM_SVC_SSD,
SSD_DECRYPT_IMG_FRAG_ID,
@@ -581,7 +592,7 @@
feature_req.feature_id = TZBSP_FVER_SSD;
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
ret = scm_call(TZBSP_SVC_INFO,
TZ_INFO_GET_FEATURE_ID,
@@ -616,7 +627,7 @@
scmcall_arg scm_arg = {0};
scmcall_ret scm_ret = {0};
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
req.status_ptr = (uint32_t*)&rsp;
req.status_len = sizeof(rsp);
@@ -661,7 +672,7 @@
arch_clean_invalidate_cache_range((addr_t) img_ptr, img_len);
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
ret = scm_call(SCM_SVC_SSD,
SSD_PROTECT_KEYSTORE_ID,
@@ -710,7 +721,7 @@
cmd_buf = (void *)&fuse_id;
cmd_len = sizeof(fuse_id);
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
/*no response */
resp_buf = NULL;
@@ -750,7 +761,7 @@
cmd_buf = (void *)&fuse_id;
cmd_len = sizeof(fuse_id);
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
/*response */
resp_len = sizeof(resp_buf);
@@ -802,7 +813,7 @@
req.partition_id = 0; /* kernel */
memcpy(req.digest, digest, sizeof(req.digest));
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
svc_id = SCM_SVC_ES;
cmd_id = SCM_SAVE_PARTITION_HASH_ID;
@@ -846,7 +857,7 @@
req.out_buf_size = out_buf_size;
req.direction = direction;
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
svc_id = SCM_SVC_MDTP;
cmd_id = SCM_MDTP_CIPHER_DIP;
@@ -902,7 +913,7 @@
req.row_data = row_data;
req.qfprom_api_status = qfprom_api_status;
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
svc_id = SCM_SVC_FUSE;
cmd_id = SCM_QFPROM_READ_ROW_ID;
@@ -956,7 +967,7 @@
uint32_t chn_id;
}__PACKED switch_ce_chn_buf;
- if (scm_arm_support)
+ if (is_scm_armv8_support())
{
dprintf(INFO, "%s:SCM call is not supported\n",__func__);
return 0;
@@ -982,7 +993,7 @@
int ret = 0;
scmcall_arg scm_arg = {0};
- if (scm_arm_support) {
+ if (is_scm_armv8_support()) {
scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER);
scm_arg.x1 = MAKE_SCM_ARGS(0x1);
scm_arg.x2 = 0;
@@ -994,7 +1005,7 @@
/* Retry with the SCM_IO_DISABLE_PMIC_ARBITER1 func ID if the above Func ID fails*/
if(ret) {
- if (scm_arm_support) {
+ if (is_scm_armv8_support()) {
scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_PWR, SCM_IO_DISABLE_PMIC_ARBITER1);
scm_arg.x1 = MAKE_SCM_ARGS(0x1);
scm_arg.x2 = 0;
@@ -1035,7 +1046,7 @@
/* Response Buffer = Null as no response expected */
dprintf(INFO, "Jumping to kernel via monitor\n");
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
/* Command Buffer */
cmd_buf = (void *)¶m;
@@ -1065,7 +1076,7 @@
struct tz_prng_data data;
scmcall_arg scm_arg = {0};
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
data.out_buf = (uint8_t*) rbuf;
data.out_buf_size = r_len;
@@ -1119,7 +1130,7 @@
scmcall_arg scm_arg = {0};
scmcall_ret scm_ret = {0};
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
cmd.config = ERR_FATAL_ENABLE;
cmd.spare = 0;
@@ -1230,7 +1241,7 @@
scmcall_arg scm_arg = {0};
scmcall_ret scm_ret = {0};
- if (!scm_arm_support) {
+ if (!is_scm_armv8_support()) {
ret = scm_call(TZBSP_SVC_INFO, IS_SECURE_BOOT_ENABLED, NULL, 0, &resp, sizeof(resp));
} else {
scm_arg.x0 = MAKE_SIP_SCM_CMD(TZBSP_SVC_INFO, IS_SECURE_BOOT_ENABLED);
@@ -1262,7 +1273,7 @@
scmcall_arg scm_arg = {0};
scmcall_ret scm_ret = {0};
- if (!scm_arm_support) {
+ if (!is_scm_armv8_support()) {
ret = scm_call_atomic(SCM_SVC_IO, SCM_IO_READ, address);
} else {
scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_IO, SCM_IO_READ);
@@ -1270,6 +1281,9 @@
scm_arg.x2 = address;
scm_arg.atomic = true;
ret = scm_call2(&scm_arg, &scm_ret);
+ /* Return the value read if the call is successful */
+ if (!ret)
+ ret = scm_ret.x1;
}
return ret;
}
@@ -1280,7 +1294,7 @@
scmcall_arg scm_arg = {0};
scmcall_ret scm_ret = {0};
- if (!scm_arm_support) {
+ if (!is_scm_armv8_support()) {
ret = scm_call_atomic2(SCM_SVC_IO, SCM_IO_WRITE, address, val);
} else {
scm_arg.x0 = MAKE_SIP_SCM_CMD(SCM_SVC_IO, SCM_IO_WRITE);
@@ -1299,7 +1313,7 @@
scmcall_arg scm_arg = {0};
scmcall_ret scm_ret = {0};
- if (!scm_arm_support)
+ if (!is_scm_armv8_support())
{
ret = scm_call_atomic2(svc, cmd, arg1, arg2);
} else {
@@ -1354,6 +1368,7 @@
bool scm_device_enter_dload()
{
uint32_t ret = 0;
+ uint32_t dload_mode = 0;
scmcall_arg scm_arg = {0};
scmcall_ret scm_ret = {0};
@@ -1363,7 +1378,14 @@
if (ret)
dprintf(CRITICAL, "SCM call to check dload mode failed: %x\n", ret);
- if (!ret && (scm_io_read(TCSR_BOOT_MISC_DETECT) == SCM_DLOAD_MODE))
+ if (!ret)
+ {
+ dload_mode = scm_io_read(TCSR_BOOT_MISC_DETECT);
+ if (board_soc_version() < 0x30000)
+ dload_mode = (dload_mode >> 16) & 0xFFFF;
+ }
+
+ if (dload_mode == SCM_DLOAD_MODE)
return true;
return false;