diff --git a/drivers/soc/qcom/spss_utils.c b/drivers/soc/qcom/spss_utils.c index 4dc78a7898dd..da4f0d15cc9c 100644 --- a/drivers/soc/qcom/spss_utils.c +++ b/drivers/soc/qcom/spss_utils.c @@ -65,35 +65,53 @@ static u32 spss_emul_type_reg_addr; /* TCSR_SOC_EMULATION_TYPE */ static void *iar_notif_handle; static struct notifier_block *iar_nb; static bool is_iar_active; +static bool is_ssr_disabled; #define CMAC_SIZE_IN_BYTES (128/8) /* 128 bit = 16 bytes */ #define CMAC_SIZE_IN_DWORDS (CMAC_SIZE_IN_BYTES/sizeof(u32)) /* 4 dwords */ -/* Asym , Crypt , Keym */ -#define NUM_UEFI_APPS 3 - static u32 pil_addr; static u32 pil_size; -static u32 cmac_buf[CMAC_SIZE_IN_DWORDS]; /* saved cmac */ -static u32 pbl_cmac_buf[CMAC_SIZE_IN_DWORDS]; /* pbl cmac */ -static u32 calc_apps_cmac[NUM_UEFI_APPS][CMAC_SIZE_IN_DWORDS]; -static u32 saved_apps_cmac[NUM_UEFI_APPS][CMAC_SIZE_IN_DWORDS]; +/* + * The saved fw cmac is stored in file in IAR-DB. + * It is provided via ioctl from user space spu service. + */ +static u32 saved_fw_cmac[CMAC_SIZE_IN_DWORDS]; /* saved fw cmac */ -#define FW_AND_APPS_CMAC_SIZE \ - (CMAC_SIZE_IN_DWORDS + NUM_UEFI_APPS*CMAC_SIZE_IN_DWORDS) +/* + * The calculated fw cmac is calculated by SPU PBL. + * It is read from shared memory and provided back to user space service + * via device attribute. + */ +static u32 calc_fw_cmac[CMAC_SIZE_IN_DWORDS]; /* calculated pbl fw cmac */ -static u32 iar_state; -static bool is_iar_enabled; -static bool ssr_disabled_flag; +/* + * The saved apps cmac is stored in file in IAR-DB. + * It is provided via ioctl from user space spu service. + */ +static u32 saved_apps_cmac[MAX_SPU_UEFI_APPS][CMAC_SIZE_IN_DWORDS]; + +/* + * The calculated apps cmac is calculated by SPU firmware. + * It is read from shared memory and provided back to user space service + * via device attribute. + */ +static u32 calc_apps_cmac[MAX_SPU_UEFI_APPS][CMAC_SIZE_IN_DWORDS]; static void __iomem *cmac_mem; -static size_t cmac_mem_size = SZ_4K; /* XPU align to 4KB */ static phys_addr_t cmac_mem_addr; +#define CMAC_MEM_SIZE SZ_4K /* XPU align to 4KB */ + +#define SPSS_BASE_ADDR_MASK 0xFFFF0000 +#define SPSS_RMB_CODE_SIZE_REG_OFFSET 0x1008 #define SPU_EMULATUION (BIT(0) | BIT(1)) #define SPU_PRESENT_IN_EMULATION BIT(0) +/* IOCTL max request size is 1KB */ +#define MAX_IOCTL_REQ_SIZE 1024 + /* Events notification */ static struct completion spss_events[SPSS_NUM_EVENTS]; static bool spss_events_signaled[SPSS_NUM_EVENTS]; @@ -117,12 +135,12 @@ struct spss_utils_device { static struct spss_utils_device *spss_utils_dev; /* static functions declaration */ -static int spss_set_fw_cmac(u32 *cmac, size_t cmac_size); -static int spss_get_pbl_and_apps_calc_cmac(void); - -static int spss_get_saved_uefi_apps_cmac(void); +static int spss_set_saved_fw_cmac(u32 *cmac, size_t cmac_size); static int spss_set_saved_uefi_apps_cmac(void); +static int spss_get_fw_calc_cmac(void); +static int spss_get_apps_calc_cmac(void); + /*==========================================================================*/ /* Device Sysfs */ /*==========================================================================*/ @@ -213,85 +231,26 @@ static ssize_t spss_debug_reg_show(struct device *dev, static DEVICE_ATTR_RO(spss_debug_reg); -static ssize_t cmac_buf_show(struct device *dev, +static ssize_t calc_fw_cmac_show(struct device *dev, struct device_attribute *attr, char *buf) { - int ret = 0; - if (!dev || !attr || !buf) { pr_err("invalid param.\n"); return -EINVAL; } - ret = snprintf(buf, PAGE_SIZE, "0x%08x,0x%08x,0x%08x,0x%08x\n", - cmac_buf[0], cmac_buf[1], cmac_buf[2], cmac_buf[3]); + /* first make sure the calc cmac is updated */ + spss_get_fw_calc_cmac(); - return ret; + memcpy(buf, calc_fw_cmac, sizeof(calc_fw_cmac)); + + return sizeof(calc_fw_cmac); } -static DEVICE_ATTR_RO(cmac_buf); +static DEVICE_ATTR_RO(calc_fw_cmac); -static ssize_t iar_state_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret = 0; - - if (!dev || !attr || !buf) { - pr_err("invalid param.\n"); - return -EINVAL; - } - - /* show IAR-STATE from soc fuse */ - ret = snprintf(buf, PAGE_SIZE, "0x%x\n", iar_state); - - return ret; -} - -static DEVICE_ATTR_RO(iar_state); - -static ssize_t iar_enabled_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret = 0; - - if (!dev || !attr || !buf) { - pr_err("invalid param.\n"); - return -EINVAL; - } - - ret = snprintf(buf, PAGE_SIZE, "0x%x\n", is_iar_enabled); - - return ret; -} - -static DEVICE_ATTR_RO(iar_enabled); - -static ssize_t pbl_cmac_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret = 0; - - if (!dev || !attr || !buf) { - pr_err("invalid param.\n"); - return -EINVAL; - } - - /* first make sure the pbl cmac is updated */ - spss_get_pbl_and_apps_calc_cmac(); - - ret = snprintf(buf, PAGE_SIZE, "0x%08x,0x%08x,0x%08x,0x%08x\n", - pbl_cmac_buf[0], pbl_cmac_buf[1], pbl_cmac_buf[2], pbl_cmac_buf[3]); - - return ret; -} - -static DEVICE_ATTR_RO(pbl_cmac); - -static ssize_t apps_cmac_show(struct device *dev, +static ssize_t calc_apps_cmac_show(struct device *dev, struct device_attribute *attr, char *buf) { if (!dev || !attr || !buf) { @@ -299,15 +258,15 @@ static ssize_t apps_cmac_show(struct device *dev, return -EINVAL; } - /* first make sure the pbl cmac is updated */ - spss_get_pbl_and_apps_calc_cmac(); + /* first make sure the calc cmac is updated */ + spss_get_apps_calc_cmac(); memcpy(buf, calc_apps_cmac, sizeof(calc_apps_cmac)); return sizeof(calc_apps_cmac); } -static DEVICE_ATTR_RO(apps_cmac); +static DEVICE_ATTR_RO(calc_apps_cmac); /*--------------------------------------------------------------------------*/ static int spss_create_sysfs(struct device *dev) @@ -332,47 +291,23 @@ static int spss_create_sysfs(struct device *dev) goto remove_test_fuse_state; } - ret = device_create_file(dev, &dev_attr_cmac_buf); + ret = device_create_file(dev, &dev_attr_calc_fw_cmac); if (ret < 0) { - pr_err("failed to create sysfs file for cmac_buf.\n"); + pr_err("failed to create sysfs file for calc_fw_cmac.\n"); goto remove_spss_debug_reg; } - ret = device_create_file(dev, &dev_attr_iar_state); + ret = device_create_file(dev, &dev_attr_calc_apps_cmac); if (ret < 0) { - pr_err("failed to create sysfs file for iar_state.\n"); - goto remove_cmac_buf; - } - - ret = device_create_file(dev, &dev_attr_iar_enabled); - if (ret < 0) { - pr_err("failed to create sysfs file for iar_enabled.\n"); - goto remove_iar_state; - } - - ret = device_create_file(dev, &dev_attr_pbl_cmac); - if (ret < 0) { - pr_err("failed to create sysfs file for pbl_cmac.\n"); - goto remove_iar_enabled; - } - - ret = device_create_file(dev, &dev_attr_apps_cmac); - if (ret < 0) { - pr_err("failed to create sysfs file for apps_cmac.\n"); - goto remove_pbl_cmac; + pr_err("failed to create sysfs file for calc_apps_cmac.\n"); + goto remove_calc_fw_cmac; } return 0; -remove_pbl_cmac: - device_remove_file(dev, &dev_attr_pbl_cmac); -remove_iar_enabled: - device_remove_file(dev, &dev_attr_iar_enabled); -remove_iar_state: - device_remove_file(dev, &dev_attr_iar_state); -remove_cmac_buf: - device_remove_file(dev, &dev_attr_cmac_buf); +remove_calc_fw_cmac: + device_remove_file(dev, &dev_attr_calc_fw_cmac); remove_spss_debug_reg: device_remove_file(dev, &dev_attr_spss_debug_reg); remove_test_fuse_state: @@ -385,11 +320,8 @@ remove_firmware_name: static void spss_destroy_sysfs(struct device *dev) { - device_remove_file(dev, &dev_attr_apps_cmac); - device_remove_file(dev, &dev_attr_pbl_cmac); - device_remove_file(dev, &dev_attr_iar_enabled); - device_remove_file(dev, &dev_attr_iar_state); - device_remove_file(dev, &dev_attr_cmac_buf); + device_remove_file(dev, &dev_attr_calc_apps_cmac); + device_remove_file(dev, &dev_attr_calc_fw_cmac); device_remove_file(dev, &dev_attr_spss_debug_reg); device_remove_file(dev, &dev_attr_test_fuse_state); device_remove_file(dev, &dev_attr_firmware_name); @@ -499,16 +431,70 @@ static int spss_is_event_signaled(struct spss_ioc_is_signaled *req) return 0; } +static int spss_handle_set_fw_and_apps_cmac(struct spss_ioc_set_fw_and_apps_cmac *req) +{ + int ret = 0; + u32 cmac_buf_size = req->cmac_buf_size; + void __user *cmac_buf_ptr = u64_to_user_ptr(req->cmac_buf_ptr); + u32 num_of_cmacs = req->num_of_cmacs; + /* Saved cmacs of spu firmware and UEFI loaded spu apps */ + u32 fw_and_apps_cmacs[1+MAX_SPU_UEFI_APPS][CMAC_SIZE_IN_DWORDS]; + + pr_debug("cmac_buf_size [0x%x].\n", (int) req->cmac_buf_size); + pr_debug("cmac_buf_ptr [0x%x].\n", (int) req->cmac_buf_ptr); + pr_debug("num_of_cmacs [0x%x].\n", (int) req->num_of_cmacs); + + if (cmac_buf_size != sizeof(fw_and_apps_cmacs)) { + pr_err("cmac_buf_size [0x%x] invalid.\n", cmac_buf_size); + return -EINVAL; + } + + if (num_of_cmacs > (u32)(MAX_SPU_UEFI_APPS+1)) { + pr_err("num_of_cmacs [0x%x] invalid.\n", num_of_cmacs); + return -EINVAL; + } + + /* copy the saved cmacs from user buffer to loacl variable */ + ret = copy_from_user(fw_and_apps_cmacs, cmac_buf_ptr, cmac_buf_size); + if (ret < 0) { + pr_err("copy_from_user() from cmac_buf_ptr failed.\n"); + return -EFAULT; + } + + /* store the saved fw cmac */ + memcpy(saved_fw_cmac, fw_and_apps_cmacs[0], + sizeof(saved_fw_cmac)); + + pr_debug("saved fw cmac: 0x%08x,0x%08x,0x%08x,0x%08x\n", + saved_fw_cmac[0], saved_fw_cmac[1], + saved_fw_cmac[2], saved_fw_cmac[3]); + + /* store the saved apps cmac */ + memcpy(saved_apps_cmac, fw_and_apps_cmacs[1], + sizeof(saved_apps_cmac)); + + /* + * SPSS is loaded now by UEFI, + * so PIL-IAR-callback is not being called on power-up by PIL. + * therefore get the saved spu fw cmac and apps cmac from ioctl. + * The PIL-IAR-callback shall be called on spss SSR. + * The saved cmacs are used on SUBSYS_BEFORE_AUTH_AND_RESET event ! + */ + spss_set_saved_fw_cmac(saved_fw_cmac, sizeof(saved_fw_cmac)); + spss_set_saved_uefi_apps_cmac(); + + pr_debug("completed ok\n"); + + return 0; +} + static long spss_utils_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret; void *buf = (void *) arg; - unsigned char data[64] = {0}; + uint8_t data[MAX_IOCTL_REQ_SIZE] = {0}; size_t size = 0; - u32 i = 0; - /* Saved cmacs of spu firmware and UEFI loaded spu apps */ - u32 fw_and_apps_cmacs[FW_AND_APPS_CMAC_SIZE]; void *req = (void *) data; if (buf == NULL) { @@ -532,36 +518,23 @@ static long spss_utils_ioctl(struct file *file, } switch (cmd) { - case SPSS_IOC_SET_FW_CMAC: - if (size != sizeof(fw_and_apps_cmacs)) { - pr_err("cmd [0x%x] invalid size [0x%x]\n", cmd, size); - return -EINVAL; - } + case SPSS_IOC_SET_FW_AND_APPS_CMAC: + pr_debug("ioctl [SPSS_IOC_SET_FW_AND_APPS_CMAC]\n"); /* spdaemon uses this ioctl only when IAR is active */ is_iar_active = true; - memcpy(fw_and_apps_cmacs, data, sizeof(fw_and_apps_cmacs)); - memcpy(cmac_buf, fw_and_apps_cmacs, sizeof(cmac_buf)); - - for (i = 0; i < NUM_UEFI_APPS; ++i) { - int x = (i+1)*CMAC_SIZE_IN_DWORDS; - - memcpy(saved_apps_cmac[i], - fw_and_apps_cmacs + x, - CMAC_SIZE_IN_BYTES); + if (cmac_mem == NULL) { + cmac_mem = ioremap_nocache(cmac_mem_addr, CMAC_MEM_SIZE); + if (!cmac_mem) { + pr_err("can't map cmac_mem.\n"); + return -EFAULT; + } } - /* - * SPSS is loaded now by UEFI, - * so IAR callback is not being called on power-up by PIL. - * therefore read the spu pbl fw cmac and apps cmac from ioctl. - * The callback shall be called on spss SSR. - */ - pr_debug("read pbl cmac from shared memory\n"); - spss_set_fw_cmac(cmac_buf, sizeof(cmac_buf)); - spss_set_saved_uefi_apps_cmac(); - spss_get_saved_uefi_apps_cmac(); + ret = spss_handle_set_fw_and_apps_cmac(req); + if (ret < 0) + return ret; break; case SPSS_IOC_WAIT_FOR_EVENT: @@ -608,9 +581,9 @@ static long spss_utils_ioctl(struct file *file, } if (is_iar_active) { - memcpy(&ssr_disabled_flag, data, size); + memcpy(&is_ssr_disabled, data, size); pr_debug("SSR disabled state updated to: %d\n", - ssr_disabled_flag); + is_ssr_disabled); } break; @@ -700,6 +673,30 @@ static void spss_utils_destroy_chardev(void) /* Device Tree */ /*==========================================================================*/ +/* get the ACTUAL spss PIL firmware size from spu reg */ +static int get_pil_size(phys_addr_t base_addr) +{ + u32 spss_code_size_addr = 0; + void __iomem *spss_code_size_reg = NULL; + u32 pil_size = 0; + + spss_code_size_addr = base_addr + SPSS_RMB_CODE_SIZE_REG_OFFSET; + spss_code_size_reg = ioremap_nocache(spss_code_size_addr, sizeof(u32)); + if (!spss_code_size_reg) { + pr_err("can't map spss_code_size_addr\n"); + return -EINVAL; + } + pil_size = readl_relaxed(spss_code_size_reg); + iounmap(spss_code_size_reg); + + if (pil_size % SZ_4K) { + pr_err("pil_size [0x%08x] is not 4K aligned.\n", pil_size); + return -EFAULT; + } + + return pil_size; +} + /** * spss_parse_dt() - Parse Device Tree info. */ @@ -714,22 +711,13 @@ static int spss_parse_dt(struct device_node *node) u32 spss_fuse2_bit = 0; u32 spss_fuse2_mask = 0; void __iomem *spss_fuse2_reg = NULL; - /* IAR_FEATURE_ENABLED soc fuse */ - u32 spss_fuse3_addr = 0; - u32 spss_fuse3_bit = 0; - u32 spss_fuse3_mask = 0; - void __iomem *spss_fuse3_reg = NULL; - /* IAR_STATE soc fuses */ - u32 spss_fuse4_addr = 0; - u32 spss_fuse4_bit = 0; - u32 spss_fuse4_mask = 0; - void __iomem *spss_fuse4_reg = NULL; struct device_node *np; struct resource r; u32 val1 = 0; u32 val2 = 0; void __iomem *spss_emul_type_reg = NULL; u32 spss_emul_type_val = 0; + phys_addr_t spss_regs_base_addr = 0; ret = of_property_read_string(node, "qcom,spss-dev-firmware-name", &dev_firmware_name); @@ -884,12 +872,14 @@ static int spss_parse_dt(struct device_node *node) pil_addr = (u32)r.start; } - ret = of_property_read_u32(node, "qcom,pil-size", - &pil_size); + spss_regs_base_addr = + (spss_debug_reg_addr & SPSS_BASE_ADDR_MASK); + ret = get_pil_size(spss_regs_base_addr); if (ret < 0) { - pr_err("can't get pil_size\n"); + pr_err("failed to get pil_size.\n"); return -EFAULT; } + pil_size = (u32) ret; pr_debug("pil_addr [0x%08x].\n", pil_addr); pr_debug("pil_size [0x%08x].\n", pil_size); @@ -898,104 +888,64 @@ static int spss_parse_dt(struct device_node *node) cmac_mem_addr = pil_addr + pil_size; pr_info("iar_buf_addr [0x%08x].\n", cmac_mem_addr); - ret = of_property_read_u32(node, "qcom,spss-fuse3-addr", - &spss_fuse3_addr); - if (ret < 0) { - pr_err("can't get fuse3 addr.\n"); - return -EFAULT; - } - - ret = of_property_read_u32(node, "qcom,spss-fuse3-bit", - &spss_fuse3_bit); - if (ret < 0) { - pr_err("can't get fuse3 bit.\n"); - return -EFAULT; - } - - spss_fuse3_reg = ioremap_nocache(spss_fuse3_addr, sizeof(u32)); - - if (!spss_fuse3_reg) { - pr_err("can't map fuse3 addr.\n"); - return -EFAULT; - } - - /* read IAR_FEATURE_ENABLED from soc fuse */ - val1 = readl_relaxed(spss_fuse3_reg); - iounmap(spss_fuse3_reg); - spss_fuse3_mask = (1<> spss_fuse4_bit) & 0x07; - - iar_state = val1; - - pr_debug("iar_state [%d]\n", iar_state); + memset(saved_fw_cmac, 0xA5, sizeof(saved_fw_cmac)); + memset(saved_apps_cmac, 0xA5, sizeof(saved_apps_cmac)); return 0; } -static int spss_set_fw_cmac(u32 *cmac, size_t cmac_size) +static int spss_set_saved_fw_cmac(u32 *cmac, size_t cmac_size) { u8 __iomem *reg = NULL; int i; if (cmac_mem == NULL) { - cmac_mem = ioremap_nocache(cmac_mem_addr, cmac_mem_size); - if (!cmac_mem) { - pr_err("can't map cmac_mem.\n"); - return -EFAULT; - } + pr_err("invalid cmac_mem.\n"); + return -EFAULT; } - pr_debug("pil_addr [0x%x]\n", pil_addr); - pr_debug("pil_size [0x%x]\n", pil_size); - pr_debug("cmac_mem [%pK]\n", cmac_mem); reg = cmac_mem; - pr_debug("reg [%pK]\n", reg); - for (i = 0; i < cmac_size/4; i++) { + for (i = 0; i < cmac_size/sizeof(u32); i++) writel_relaxed(cmac[i], reg + i*sizeof(u32)); - pr_debug("cmac[%d] [0x%x]\n", i, cmac[i]); - } - reg += cmac_size; + pr_debug("saved fw cmac: 0x%08x,0x%08x,0x%08x,0x%08x\n", + cmac[0], cmac[1], cmac[2], cmac[3]); + return 0; } -static int spss_get_pbl_and_apps_calc_cmac(void) +static int spss_get_fw_calc_cmac(void) +{ + u8 __iomem *reg = NULL; + int i; + u32 val; + + if (cmac_mem == NULL) { + pr_err("invalid cmac_mem.\n"); + return -EFAULT; + } + + reg = cmac_mem; /* IAR buffer base */ + reg += CMAC_SIZE_IN_BYTES; /* skip the saved cmac */ + + memset(calc_fw_cmac, 0, sizeof(calc_fw_cmac)); + + /* get pbl fw cmac from ddr */ + for (i = 0; i < CMAC_SIZE_IN_DWORDS; i++) { + val = readl_relaxed(reg); + calc_fw_cmac[i] = val; + reg += sizeof(u32); + } + + pr_debug("calc_fw_cmac : 0x%08x,0x%08x,0x%08x,0x%08x\n", + calc_fw_cmac[0], calc_fw_cmac[1], + calc_fw_cmac[2], calc_fw_cmac[3]); + + return 0; +} + +static int spss_get_apps_calc_cmac(void) { u8 __iomem *reg = NULL; int i, j; @@ -1005,23 +955,14 @@ static int spss_get_pbl_and_apps_calc_cmac(void) return -EFAULT; reg = cmac_mem; /* IAR buffer base */ - reg += CMAC_SIZE_IN_BYTES; /* skip the saved cmac */ - pr_debug("reg [%pK]\n", reg); + reg += CMAC_SIZE_IN_BYTES; /* skip the saved fw cmac */ + reg += CMAC_SIZE_IN_BYTES; /* skip the calc fw cmac */ + reg += CMAC_SIZE_IN_BYTES; /* skip the saved 1st app cmac */ - /* get pbl fw cmac from ddr */ - for (i = 0; i < CMAC_SIZE_IN_DWORDS; i++) { - val = readl_relaxed(reg); - pbl_cmac_buf[i] = val; - reg += sizeof(u32); - } - reg += CMAC_SIZE_IN_BYTES; /* skip the saved cmac */ - - pr_debug("pbl_cmac_buf : 0x%08x,0x%08x,0x%08x,0x%08x\n", - pbl_cmac_buf[0], pbl_cmac_buf[1], - pbl_cmac_buf[2], pbl_cmac_buf[3]); + memset(calc_apps_cmac, 0, sizeof(calc_apps_cmac)); /* get apps cmac from ddr */ - for (j = 0; j < NUM_UEFI_APPS; j++) { + for (j = 0; j < ARRAY_SIZE(calc_apps_cmac); j++) { for (i = 0; i < CMAC_SIZE_IN_DWORDS; i++) { val = readl_relaxed(reg); calc_apps_cmac[j][i] = val; @@ -1029,6 +970,11 @@ static int spss_get_pbl_and_apps_calc_cmac(void) } reg += CMAC_SIZE_IN_BYTES; /* skip the saved cmac */ + /* check for any pattern to mark end of cmacs */ + if (saved_apps_cmac[j][0] == saved_apps_cmac[j][1]) { + memset(calc_apps_cmac[j], 0, sizeof(calc_apps_cmac[j])); + break; /* no more cmacs */ + } pr_debug("app [%d] cmac : 0x%08x,0x%08x,0x%08x,0x%08x\n", j, calc_apps_cmac[j][0], calc_apps_cmac[j][1], calc_apps_cmac[j][2], calc_apps_cmac[j][3]); @@ -1037,37 +983,6 @@ static int spss_get_pbl_and_apps_calc_cmac(void) return 0; } -static int spss_get_saved_uefi_apps_cmac(void) -{ - u8 __iomem *reg = NULL; - int i, j; - u32 val; - - if (cmac_mem == NULL) - return -EFAULT; - - reg = cmac_mem; /* IAR buffer base */ - reg += (2*CMAC_SIZE_IN_BYTES); /* skip the saved and calc fw cmac */ - pr_debug("reg [%pK]\n", reg); - - /* get saved apps cmac from ddr - were written by UEFI spss driver */ - for (j = 0; j < NUM_UEFI_APPS; j++) { - for (i = 0; i < CMAC_SIZE_IN_DWORDS; i++) { - val = readl_relaxed(reg); - saved_apps_cmac[j][i] = val; - reg += sizeof(u32); - } - reg += CMAC_SIZE_IN_BYTES; /* skip the calc cmac */ - - pr_debug("app[%d] saved cmac: 0x%08x,0x%08x,0x%08x,0x%08x\n", - j, - saved_apps_cmac[j][0], saved_apps_cmac[j][1], - saved_apps_cmac[j][2], saved_apps_cmac[j][3]); - } - - return 0; -} - static int spss_set_saved_uefi_apps_cmac(void) { u8 __iomem *reg = NULL; @@ -1079,10 +994,11 @@ static int spss_set_saved_uefi_apps_cmac(void) reg = cmac_mem; /* IAR buffer base */ reg += (2*CMAC_SIZE_IN_BYTES); /* skip the saved and calc fw cmac */ - pr_debug("reg [%pK]\n", reg); /* get saved apps cmac from ddr - were written by UEFI spss driver */ - for (j = 0; j < NUM_UEFI_APPS; j++) { + for (j = 0; j < MAX_SPU_UEFI_APPS; j++) { + if (saved_apps_cmac[j][0] == saved_apps_cmac[j][1]) + break; /* no more cmacs */ for (i = 0; i < CMAC_SIZE_IN_DWORDS; i++) { val = saved_apps_cmac[j][i]; writel_relaxed(val, reg); @@ -1132,8 +1048,8 @@ static int spss_utils_pil_callback(struct notifier_block *nb, break; case SUBSYS_BEFORE_POWERUP: pr_debug("[SUBSYS_BEFORE_POWERUP] event.\n"); - if (is_iar_active && ssr_disabled_flag) { - pr_warn("SPSS SSR disabled, requesting reboot\n"); + if (is_iar_active && is_ssr_disabled) { + pr_err("SPSS SSR disabled, requesting reboot\n"); kernel_restart("SPSS SSR disabled, requesting reboot"); } break; @@ -1159,12 +1075,12 @@ static int spss_utils_pil_callback(struct notifier_block *nb, pr_debug("[SUBSYS_PROXY_UNVOTE] event.\n"); break; case SUBSYS_BEFORE_AUTH_AND_RESET: + pr_debug("[SUBSYS_BEFORE_AUTH_AND_RESET] event.\n"); /* do nothing if IAR is not active */ if (!is_iar_active) return NOTIFY_OK; - pr_debug("[SUBSYS_BEFORE_AUTH_AND_RESET] event.\n"); - /* Called on SSR as spss firmware is loaded by UEFI */ - spss_set_fw_cmac(cmac_buf, sizeof(cmac_buf)); + /* Called on SSR as spss firmware is loaded by UEFI on boot */ + spss_set_saved_fw_cmac(saved_fw_cmac, sizeof(saved_fw_cmac)); spss_set_saved_uefi_apps_cmac(); break; default: @@ -1253,7 +1169,7 @@ static int spss_probe(struct platform_device *pdev) } mutex_init(&event_lock); - ssr_disabled_flag = false; + is_ssr_disabled = false; pr_info("Probe completed successfully, [%s].\n", firmware_name); diff --git a/include/uapi/linux/spss_utils.h b/include/uapi/linux/spss_utils.h index 0220a2af477d..d13340bf556c 100644 --- a/include/uapi/linux/spss_utils.h +++ b/include/uapi/linux/spss_utils.h @@ -19,12 +19,14 @@ #define SPSS_IOC_MAGIC 'S' /* ---------- set fw cmac --------------------------------- */ -#define NUM_SPU_UEFI_APPS 3 +#define OLD_NUM_SPU_UEFI_APPS 3 /* Obsolete */ + #define CMAC_SIZE_IN_WORDS 4 +/* Obsolete struct, keep for backward compatible */ struct spss_ioc_set_fw_cmac { __u32 cmac[CMAC_SIZE_IN_WORDS]; - __u32 app_cmacs[NUM_SPU_UEFI_APPS][CMAC_SIZE_IN_WORDS]; + __u32 apps_cmac[OLD_NUM_SPU_UEFI_APPS][CMAC_SIZE_IN_WORDS]; } __packed; #define SPSS_IOC_SET_FW_CMAC \ @@ -78,7 +80,28 @@ struct spss_ioc_is_signaled { #define SPSS_IOC_IS_EVENT_SIGNALED \ _IOWR(SPSS_IOC_MAGIC, 4, struct spss_ioc_is_signaled) +/* ---------- set ssr state ------------------------------ */ + #define SPSS_IOC_SET_SSR_STATE \ _IOWR(SPSS_IOC_MAGIC, 5, __u32) +/* ---------- set fw and apps cmac --------------------------------- */ + +/* Asym , Crypt , Keym + 3rd party uefi apps */ +#define MAX_SPU_UEFI_APPS 8 + +/** use variable-size-array for future growth */ +struct spss_ioc_set_fw_and_apps_cmac { + __u64 cmac_buf_ptr; + /* + * expected cmac_buf_size is: + * (1+MAX_SPU_UEFI_APPS)*CMAC_SIZE_IN_WORDS*sizeof(uint32_t) + */ + __u32 cmac_buf_size; + __u32 num_of_cmacs; +} __attribute__((packed)); + +#define SPSS_IOC_SET_FW_AND_APPS_CMAC \ + _IOWR(SPSS_IOC_MAGIC, 6, struct spss_ioc_set_fw_and_apps_cmac) + #endif /* _UAPI_SPSS_UTILS_H_ */