diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-08-15 10:58:08 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-08-15 10:58:08 +0200 |
commit | bd1fbce74f79d647af4ee338f9193351811e80f4 (patch) | |
tree | dc119b20a406c2f7f9df0d1b7990deb876a402a4 /drivers/hab | |
parent | 53e145d550c1ee9db907fccd7ad4d98d6aee806b (diff) | |
parent | dd5dfb6ff467f6d640e48046acedfe435c649c94 (diff) | |
download | barebox-bd1fbce74f79d647af4ee338f9193351811e80f4.tar.gz barebox-bd1fbce74f79d647af4ee338f9193351811e80f4.tar.xz |
Merge branch 'for-next/imx8-hab'
Diffstat (limited to 'drivers/hab')
-rw-r--r-- | drivers/hab/hab.c | 2 | ||||
-rw-r--r-- | drivers/hab/habv4.c | 134 |
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); |