Merge "soc: qcom: spss_utils: IAR 3rd party uefi app"

This commit is contained in:
qctecmdr 2020-09-19 09:09:16 -07:00 • committed by Gerrit - the friendly Code Review server
commit d09483fe6c
2 changed files with 227 additions and 288 deletions

View file

@ -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);

View file

@ -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_ */