mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "soc: qcom: spss_utils: IAR 3rd party uefi app"
This commit is contained in:
commit
d09483fe6c
2 changed files with 227 additions and 288 deletions
|
|
@ -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_fuse3_bit);
|
||||
pr_debug("iar_enabled fuse, addr [0x%x] val [0x%x] mask [0x%x].\n",
|
||||
spss_fuse3_addr, val1, spss_fuse3_mask);
|
||||
if (val1 & spss_fuse3_mask)
|
||||
is_iar_enabled = true;
|
||||
else
|
||||
is_iar_enabled = false;
|
||||
|
||||
memset(cmac_buf, 0xA5, sizeof(cmac_buf));
|
||||
|
||||
ret = of_property_read_u32(node, "qcom,spss-fuse4-addr",
|
||||
&spss_fuse4_addr);
|
||||
if (ret < 0) {
|
||||
pr_err("can't get fuse4 addr.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "qcom,spss-fuse4-bit",
|
||||
&spss_fuse4_bit);
|
||||
if (ret < 0) {
|
||||
pr_err("can't get fuse4 bit.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
spss_fuse4_reg = ioremap_nocache(spss_fuse4_addr, sizeof(u32));
|
||||
|
||||
if (!spss_fuse4_reg) {
|
||||
pr_err("can't map fuse4 addr.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
val1 = readl_relaxed(spss_fuse4_reg);
|
||||
iounmap(spss_fuse4_reg);
|
||||
spss_fuse4_mask = (0x07 << spss_fuse4_bit); /* 3 bits */
|
||||
pr_debug("IAR_STATE fuse, addr [0x%x] val [0x%x] mask [0x%x].\n",
|
||||
spss_fuse4_addr, val1, spss_fuse4_mask);
|
||||
val1 = ((val1 & spss_fuse4_mask) >> 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue