summaryrefslogtreecommitdiffstats
path: root/drivers/hab
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-08-15 10:58:08 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-08-15 10:58:08 +0200
commitbd1fbce74f79d647af4ee338f9193351811e80f4 (patch)
treedc119b20a406c2f7f9df0d1b7990deb876a402a4 /drivers/hab
parent53e145d550c1ee9db907fccd7ad4d98d6aee806b (diff)
parentdd5dfb6ff467f6d640e48046acedfe435c649c94 (diff)
downloadbarebox-bd1fbce74f79d647af4ee338f9193351811e80f4.tar.gz
barebox-bd1fbce74f79d647af4ee338f9193351811e80f4.tar.xz
Merge branch 'for-next/imx8-hab'
Diffstat (limited to 'drivers/hab')
-rw-r--r--drivers/hab/hab.c2
-rw-r--r--drivers/hab/habv4.c134
2 files changed, 122 insertions, 14 deletions
diff --git a/drivers/hab/hab.c b/drivers/hab/hab.c
index 03bb65e0fa..a346e01567 100644
--- a/drivers/hab/hab.c
+++ b/drivers/hab/hab.c
@@ -217,7 +217,7 @@ static struct imx_hab_ops *imx_get_hab_ops(void)
if (IS_ENABLED(CONFIG_HABV3) && (cpu_is_mx25() || cpu_is_mx35()))
tmp = &imx_hab_ops_iim;
- else if (IS_ENABLED(CONFIG_HABV4) && cpu_is_mx6())
+ else if (IS_ENABLED(CONFIG_HABV4) && (cpu_is_mx6() || cpu_is_mx8mq()))
tmp = &imx_hab_ops_ocotp;
else
return NULL;
diff --git a/drivers/hab/habv4.c b/drivers/hab/habv4.c
index a53e40ad23..e3c1de1a4d 100644
--- a/drivers/hab/habv4.c
+++ b/drivers/hab/habv4.c
@@ -22,8 +22,11 @@
#include <hab.h>
#include <init.h>
#include <types.h>
+#include <linux/arm-smccc.h>
+#include <asm/cache.h>
#include <mach/generic.h>
+#include <mach/imx8mq.h>
#define HABV4_RVT_IMX28 0xffff8af8
#define HABV4_RVT_IMX6_OLD 0x00000094
@@ -177,6 +180,92 @@ struct habv4_rvt {
void (*failsafe)(void);
} __packed;
+#define FSL_SIP_HAB 0xC2000007
+#define FSL_SIP_HAB_AUTHENTICATE 0x00
+#define FSL_SIP_HAB_ENTRY 0x01
+#define FSL_SIP_HAB_EXIT 0x02
+#define FSL_SIP_HAB_REPORT_EVENT 0x03
+#define FSL_SIP_HAB_REPORT_STATUS 0x04
+#define FSL_SIP_HAB_FAILSAFE 0x05
+#define FSL_SIP_HAB_CHECK_TARGET 0x06
+
+static enum hab_status hab_sip_report_status(enum hab_config *config,
+ enum hab_state *state)
+{
+ struct arm_smccc_res res;
+
+ if (state)
+ v8_flush_dcache_range((unsigned long)state,
+ (unsigned long)state + sizeof(*config));
+ if (config)
+ v8_flush_dcache_range((unsigned long)config,
+ (unsigned long)config + sizeof(*state));
+
+ arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_STATUS,
+ (unsigned long) config,
+ (unsigned long) state, 0, 0, 0, 0, &res);
+ if (state)
+ v8_inv_dcache_range((unsigned long)state,
+ (unsigned long)state + sizeof(*config));
+ if (config)
+ v8_inv_dcache_range((unsigned long)config,
+ (unsigned long)config + sizeof(*state));
+ return (enum hab_status)res.a0;
+}
+
+static enum hab_status imx8_read_sram_events(enum hab_status status,
+ uint32_t index, void *event,
+ uint32_t *bytes)
+{
+ struct hab_event_record *events[10];
+ int num_events = 0;
+ char *sram = (char *)0x9061c0;
+ int i = 0;
+ int internal_index = 0;
+ char *end = 0;
+ struct hab_event_record *search;
+
+ /*
+ * AN12263 HABv4 Guidelines and Recommendations
+ * recommends the address and size, however errors are usually contained
+ * within the first bytes. Scan only the first few bytes to rule out
+ * lots of false positives.
+ */
+ end = sram + 0x1a0;
+
+ while (sram < end) {
+ if (*sram == 0xdb) {
+ search = (void *)sram;
+ sram = sram + be16_to_cpu(search->hdr.len);
+ events[num_events] = search;
+ num_events++;
+ } else {
+ sram++;
+ }
+ }
+ while (i < num_events) {
+ if (events[i]->status == status) {
+ if (internal_index == index) {
+ *bytes = sizeof(struct hab_event_record) +
+ be16_to_cpu(events[i]->hdr.len);
+ if (event)
+ memcpy(event, events[i], *bytes);
+ return HAB_STATUS_SUCCESS;
+ } else {
+ internal_index++;
+ }
+ }
+ i++;
+ }
+ return HAB_STATUS_FAILURE;
+}
+
+struct habv4_rvt hab_smc_ops = {
+ .header = { .tag = 0xdd },
+ .report_event = imx8_read_sram_events,
+ .report_status = hab_sip_report_status,
+};
+
static const char *habv4_get_status_str(enum hab_status status)
{
switch (status) {
@@ -496,23 +585,46 @@ int imx6_hab_get_status(void)
return -EINVAL;
}
-static int init_imx6_hab_get_status(void)
+static int imx8_hab_get_status(void)
{
- int ret = 0;
+ return habv4_get_status(&hab_smc_ops);
+}
- if (!cpu_is_mx6())
+static int init_imx8_hab_get_status(void)
+{
+ if (!cpu_is_mx8mq())
/* can happen in multi-image builds and is not an error */
return 0;
- ret = imx6_hab_get_status();
-
/*
* Nobody will check the return value if there were HAB errors, but the
* initcall will fail spectaculously with a strange error message.
*/
- if (ret == -EPERM)
+ imx8_hab_get_status();
+
+ return 0;
+}
+
+/*
+ *
+ *
+ *
+ */
+postmmu_initcall(init_imx8_hab_get_status);
+
+static int init_imx6_hab_get_status(void)
+{
+ if (!cpu_is_mx6())
+ /* can happen in multi-image builds and is not an error */
return 0;
- return ret;
+
+ /*
+ * Nobody will check the return value if there were HAB errors, but the
+ * initcall will fail spectaculously with a strange error message.
+ */
+ imx6_hab_get_status();
+
+ return 0;
}
/*
@@ -531,19 +643,15 @@ int imx28_hab_get_status(void)
static int init_imx28_hab_get_status(void)
{
- int ret = 0;
-
if (!cpu_is_mx28())
/* can happen in multi-image builds and is not an error */
return 0;
- ret = imx28_hab_get_status();
/* nobody will check the return value if there were HAB errors, but the
* initcall will fail spectaculously with a strange error message. */
- if (ret == -EPERM)
- return 0;
- return ret;
+ imx28_hab_get_status();
+ return 0;
}
/* i.MX28 ROM code can be run after MMU setup to make use of caching */
postmmu_initcall(init_imx28_hab_get_status);