summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorMikael Larsson <mikael.xt.larsson@stericsson.com>2010-09-29 11:37:46 +0200
committerMichael BRANDT <michael.brandt@stericsson.com>2010-10-05 09:22:03 +0200
commit92f109e1fb271ca9ca81e3d50435f17bea9004b2 (patch)
tree17f22b9b4f4fd5ae799547eb70a30c6bb6d1c34a /board
parent5e2a6f3f575c95ed07cd43f5bb3beed877fd3d16 (diff)
Modem loading
This adds functionality to load and execute modem in an early stage just after eMMC init. It also flushes ISSW since this will be removed in Xloader This patch depends on an updated Xloader that doesn't load modem, ipl and doesn't flush ISSW. Change-Id: I5be4a4a5af80df13e65ecd10c073b50e4d8703b9 Signed-off-by: Mikael Larsson <mikael.xt.larsson@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/5769 Reviewed-by: Michael BRANDT <michael.brandt@stericsson.com> Reviewed-by: Peter NESSRUP <peter.nessrup@stericsson.com>
Diffstat (limited to 'board')
-rw-r--r--board/st/u8500/itp.c159
-rw-r--r--board/st/u8500/itp.h4
-rw-r--r--board/st/u8500/mmc_host.c2
3 files changed, 151 insertions, 14 deletions
diff --git a/board/st/u8500/itp.c b/board/st/u8500/itp.c
index e7ef4fa7e..033d3d03c 100644
--- a/board/st/u8500/itp.c
+++ b/board/st/u8500/itp.c
@@ -13,7 +13,116 @@
#include "itp.h"
#include "cspsa_fp.h"
+#define SEC_ROM_FORCE_CLEAN_MASK 0x0020
+#define SEC_ROM_RET_OK 0x01
+#define ISSWAPI_SECURE_LOAD 0x10000002
+#define ISSWAPI_FLUSH_BOOT_CODE 0x11000003
+#define IPL_ITEM_ID 0x02
+typedef u32 (*boot_rom_bridge_func_t)(const u32 , const u32, const va_list);
+
+static boot_rom_bridge_func_t hw_sec_rom_pub_bridge;
+
+struct sec_rom_cut_desc {
+ u32 cutid_addr;
+ u32 cutid;
+ u32 bridge_func;
+};
+
+static const struct sec_rom_cut_desc cuttable[] = {
+ { 0x9001FFF4, 0x008500A0, 0x90018300 },
+ { 0x9001FFF4, 0x008500A1, 0x90018300 },
+ { 0x9001FFF4, 0x005500A0, 0x90018300 },
+ { 0x9001DBF4, 0x008500B0, 0x90017300 },
+};
+
+static u32 itp_call_secure_service(const u32 serviceid,
+ const u32 secureconfig,
+ ...)
+{
+ va_list ap;
+ u32 returnvalue;
+
+ va_start(ap, secureconfig);
+
+ returnvalue = hw_sec_rom_pub_bridge(serviceid,
+ secureconfig,
+ ap);
+
+ va_end(ap);
+ return returnvalue;
+}
+
+static int itp_init_bridge(void)
+{
+ u8 cutnb = 0;
+
+ hw_sec_rom_pub_bridge = NULL;
+
+ while ((cutnb < ARRAY_SIZE(cuttable)) &&
+ (cuttable[cutnb].cutid != *(u32 *)(cuttable[cutnb].cutid_addr)))
+ cutnb++;
+
+ if (cutnb < ARRAY_SIZE(cuttable)) {
+ hw_sec_rom_pub_bridge =
+ (boot_rom_bridge_func_t)cuttable[cutnb].bridge_func;
+ return 0;
+ }
+
+ printf("itp_init_bridge: cutid not found\n");
+ return 1;
+}
+
+static int itp_flush_issw(void)
+{
+ u32 ret;
+
+ ret = itp_call_secure_service(ISSWAPI_FLUSH_BOOT_CODE,
+ SEC_ROM_FORCE_CLEAN_MASK,
+ 0,
+ 0);
+
+ if (ret != SEC_ROM_RET_OK) {
+ printf("itp_flush_issw: ISSWAPI_FLUSH_BOOT_CODE failed: %d\n",
+ ret);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int itp_load_ipl(block_dev_desc_t *block_dev)
+{
+ u32 offset;
+ u32 size;
+ u32 loadaddr;
+ u32 returnvalue;
+ int ab8500_cutid;
+
+ debug("loadipl\n");
+
+ /* Check if IPL partition is present */
+ if (get_entry_info_toc(block_dev, ITP_TOC_IPL_NAME, &offset,
+ &size, &loadaddr)) {
+ printf("itp_load_ipl: get_entry_info_toc failed\n");
+ return 1;
+ }
+
+ /* Get CutID */
+ ab8500_cutid = ab8500_read(AB8500_MISC, AB8500_REV_REG);
+
+ returnvalue = itp_call_secure_service((u32)ISSWAPI_SECURE_LOAD,
+ SEC_ROM_FORCE_CLEAN_MASK,
+ IPL_ITEM_ID,
+ ab8500_cutid);
+ if (returnvalue != SEC_ROM_RET_OK) {
+ printf("itp_load_ipl: ISSWAPI_SECURE_LOAD failed: %d\n",
+ returnvalue);
+ return 1;
+ }
+
+ return 0;
+}
static int itp_load_toc_entry(block_dev_desc_t *block_dev,
const char *partname,
u32 *loadaddress)
@@ -47,36 +156,62 @@ static int itp_load_toc_entry(block_dev_desc_t *block_dev,
}
/*
- * itp_load_itp - Loads itp depending on config.
+ * itp_load_itp_and_modem - Loads itp and modem depending on config.
* If itp is loaded ok it will be executed and u-boot execution will stop
*/
-int itp_load_itp(block_dev_desc_t *block_dev)
+int itp_load_itp_and_modem(block_dev_desc_t *block_dev)
{
+ int retval = 0;
u32 cspsa_key;
void (*loadaddress)(void) = NULL;
- debug("\nitp_load_itp\n");
+ debug("\nitp_load_itp_and_modem\n");
+
+ if (itp_init_bridge()) {
+ retval = 1;
+ goto exit;
+ }
if (cspsa_fp_read(block_dev,
ITP_CSPSA_KEY,
&cspsa_key)) {
- printf("itp_load_itp: cspsa_fp_read failed\n");
- return 1;
+ printf("itp_load_itp_and_modem: cspsa_fp_read failed\n");
+ retval = 1;
+ goto exit;
+ }
+
+ if (cspsa_key & ITP_LOAD_MODEM) {
+ if (itp_load_toc_entry(block_dev,
+ ITP_TOC_MODEM_NAME,
+ (u32 *)loadaddress)) {
+ retval = 1;
+ goto exit;
+ }
+
+ if (itp_load_ipl(block_dev)) {
+ retval = 1;
+ goto exit;
+ }
}
if (cspsa_key & ITP_LOAD_ITP) {
if (itp_load_toc_entry(block_dev,
ITP_TOC_ITP_NAME,
(u32 *)loadaddress)) {
- printf("itp_load_itp: itp_load_partition failed\n");
- return 1;
+ retval = 1;
+ goto exit;
}
- loadaddress(); /* U-boot execution will end here*/
-
- printf("itp_load_itp: itp execution failed\n");
- return 1;
}
- return 0;
+exit:
+ /* Always Flush */
+ if (hw_sec_rom_pub_bridge != NULL)
+ itp_flush_issw();
+
+ if ((cspsa_key & ITP_LOAD_ITP) && !retval)
+ loadaddress(); /* U-boot execution will end here*/
+
+ /* Return on error */
+ return retval;
}
diff --git a/board/st/u8500/itp.h b/board/st/u8500/itp.h
index 74dc6b65b..13d039eed 100644
--- a/board/st/u8500/itp.h
+++ b/board/st/u8500/itp.h
@@ -16,9 +16,11 @@
#define ITP_LOAD_ITP 0x04
#define ITP_TOC_ITP_NAME "ITP"
+#define ITP_TOC_MODEM_NAME "MODEM"
+#define ITP_TOC_IPL_NAME "IPL"
#define ITP_CSPSA_KEY 0
-int itp_load_itp(block_dev_desc_t *block_dev);
+int itp_load_itp_and_modem(block_dev_desc_t *block_dev);
#endif /* __ITP_H__ */
diff --git a/board/st/u8500/mmc_host.c b/board/st/u8500/mmc_host.c
index a77793620..79be58acd 100644
--- a/board/st/u8500/mmc_host.c
+++ b/board/st/u8500/mmc_host.c
@@ -625,7 +625,7 @@ int board_mmc_init(bd_t *bis)
*/
#ifdef CONFIG_ITP_LOAD
- itp_load_itp(&dev->block_dev);
+ itp_load_itp_and_modem(&dev->block_dev);
#endif
dev = alloc_mmc_struct();