msm: camera: icp: Add support for non secure FW load
Starting from waipio, ICP [lx7] FW is to loaded using secure PIL. For debug purposes also added support for non secure image loading for lx7. CRs-Fixed: 2722486 Change-Id: I30026fb8e65f323ab73336e0ae787a2359bc934f Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
This commit is contained in:
142
drivers/cam_icp/utils/cam_icp_utils.c
Normal file
142
drivers/cam_icp/utils/cam_icp_utils.c
Normal file
@@ -0,0 +1,142 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cam_icp_utils.h"
|
||||
|
||||
int32_t cam_icp_validate_fw(const uint8_t *elf,
|
||||
uint32_t machine_id)
|
||||
{
|
||||
struct elf32_hdr *elf_hdr;
|
||||
|
||||
if (!elf) {
|
||||
CAM_ERR(CAM_ICP, "Invalid params");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
elf_hdr = (struct elf32_hdr *)elf;
|
||||
|
||||
if (memcmp(elf_hdr->e_ident, ELFMAG, SELFMAG)) {
|
||||
CAM_ERR(CAM_ICP, "ICP elf identifier is failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check architecture */
|
||||
if (elf_hdr->e_machine != machine_id) {
|
||||
CAM_ERR(CAM_ICP, "unsupported arch: 0x%x", elf_hdr->e_machine);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check elf bit format */
|
||||
if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32) {
|
||||
CAM_ERR(CAM_ICP, "elf doesn't support 32 bit format");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t cam_icp_get_fw_size(
|
||||
const uint8_t *elf, uint32_t *fw_size,
|
||||
struct cam_icp_proc_params *params)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
int32_t i = 0;
|
||||
uint32_t num_prg_hdrs;
|
||||
unsigned char *icp_prg_hdr_tbl;
|
||||
uint32_t seg_mem_size = 0;
|
||||
struct elf32_hdr *elf_hdr;
|
||||
struct elf32_phdr *prg_hdr;
|
||||
|
||||
if (!elf || !fw_size || !params) {
|
||||
CAM_ERR(CAM_ICP, "invalid args");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*fw_size = 0;
|
||||
|
||||
elf_hdr = (struct elf32_hdr *)elf;
|
||||
num_prg_hdrs = elf_hdr->e_phnum;
|
||||
icp_prg_hdr_tbl = (unsigned char *)elf + elf_hdr->e_phoff;
|
||||
prg_hdr = (struct elf32_phdr *)&icp_prg_hdr_tbl[0];
|
||||
|
||||
if (!prg_hdr) {
|
||||
CAM_ERR(CAM_ICP, "failed to get elf program header attr");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ICP, "num_prg_hdrs = %d", num_prg_hdrs);
|
||||
for (i = 0; i < num_prg_hdrs; i++, prg_hdr++) {
|
||||
if (prg_hdr->p_flags == 0)
|
||||
continue;
|
||||
|
||||
if ((params->skip_seg) &&
|
||||
((prg_hdr->p_vaddr == params->vaddr[0]) ||
|
||||
(prg_hdr->p_vaddr == params->vaddr[1])))
|
||||
continue;
|
||||
|
||||
seg_mem_size = (prg_hdr->p_memsz + prg_hdr->p_align - 1) &
|
||||
~(prg_hdr->p_align - 1);
|
||||
seg_mem_size += prg_hdr->p_vaddr;
|
||||
CAM_DBG(CAM_ICP, "memsz:%x align:%x addr:%x seg_mem_size:%x",
|
||||
(int)prg_hdr->p_memsz, (int)prg_hdr->p_align,
|
||||
(int)prg_hdr->p_vaddr, (int)seg_mem_size);
|
||||
if (*fw_size < seg_mem_size)
|
||||
*fw_size = seg_mem_size;
|
||||
|
||||
}
|
||||
|
||||
if (*fw_size == 0) {
|
||||
CAM_ERR(CAM_ICP, "invalid elf fw file");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t cam_icp_program_fw(const uint8_t *elf,
|
||||
uintptr_t fw_kva_addr,
|
||||
struct cam_icp_proc_params *params)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
uint32_t num_prg_hdrs;
|
||||
unsigned char *icp_prg_hdr_tbl;
|
||||
int32_t i = 0;
|
||||
u8 *dest;
|
||||
u8 *src;
|
||||
struct elf32_hdr *elf_hdr;
|
||||
struct elf32_phdr *prg_hdr;
|
||||
|
||||
elf_hdr = (struct elf32_hdr *)elf;
|
||||
num_prg_hdrs = elf_hdr->e_phnum;
|
||||
icp_prg_hdr_tbl = (unsigned char *)elf + elf_hdr->e_phoff;
|
||||
prg_hdr = (struct elf32_phdr *)&icp_prg_hdr_tbl[0];
|
||||
|
||||
if (!prg_hdr) {
|
||||
CAM_ERR(CAM_ICP, "failed to get elf program header attr");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_prg_hdrs; i++, prg_hdr++) {
|
||||
if (prg_hdr->p_flags == 0)
|
||||
continue;
|
||||
|
||||
if ((params->skip_seg) &&
|
||||
((prg_hdr->p_vaddr == params->vaddr[0]) ||
|
||||
(prg_hdr->p_vaddr == params->vaddr[1])))
|
||||
continue;
|
||||
|
||||
CAM_DBG(CAM_ICP, "Loading FW header size: %u",
|
||||
prg_hdr->p_filesz);
|
||||
if (prg_hdr->p_filesz != 0) {
|
||||
src = (u8 *)((u8 *)elf + prg_hdr->p_offset);
|
||||
dest = (u8 *)(((u8 *)fw_kva_addr) +
|
||||
prg_hdr->p_vaddr);
|
||||
|
||||
memcpy_toio(dest, src, prg_hdr->p_filesz);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
Reference in New Issue
Block a user