static int segment_is_loadable(const struct elf32_phdr *p) { return (p->p_type & PT_LOAD) && !segment_is_hash(p->p_flags); }
static int qproc_verify_segments(struct qproc *qproc, const struct firmware *fw) { struct elf32_hdr *ehdr; struct elf32_phdr *phdr; const u8 *elf_data = fw->data; unsigned long timeout; phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX; u32 size = 0; s32 val; int ret; int i; u32 v; ehdr = (struct elf32_hdr *)elf_data; phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff); v = readl_relaxed(qproc->rmb_base + RMB_PMI_CODE_LENGTH); dev_err(qproc->dev, "RMB_PMI_CODE_LENGTH: %pa\n", &v); msleep(1); #if 1 for (i = 0; i < ehdr->e_phnum; i++, phdr++) { phys_addr_t da = phdr->p_paddr; u32 memsz = phdr->p_memsz; if (!segment_is_loadable(phdr)) continue; /* if (phdr->p_type != PT_LOAD) continue; */ dev_err(qproc->dev, "0x%x %d %d\n", phdr->p_paddr, segment_is_hash(phdr->p_flags), !!(phdr->p_flags & BIT(27))); /* if (segment_is_hash(phdr->p_flags)) continue; if (memsz == 0) continue; */ if (da < min_addr) min_addr = da; size += memsz; } dev_err(qproc->dev, "verify: %pa:%pa\n", &min_addr, &size); v = readl_relaxed(qproc->rmb_base + RMB_PMI_CODE_LENGTH); dev_err(qproc->dev, "RMB_PMI_CODE_LENGTH: %pa\n", &v); #if 0 if (v == 0) { writel_relaxed(min_addr, qproc->rmb_base + RMB_PMI_CODE_START); writel(CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND); } writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH); #endif #endif v = readl_relaxed(qproc->rmb_base + RMB_PMI_CODE_LENGTH); dev_err(qproc->dev, "RMB_PMI_CODE_LENGTH: %pa\n", &v); printk("DEBUG:pil: status... %08x\n", readl_relaxed(qproc->rmb_base + RMB_MBA_STATUS)); timeout = jiffies + 10 * HZ; for (;;) { msleep(1); val = readl(qproc->rmb_base + RMB_MBA_STATUS); if (val == STATUS_AUTH_COMPLETE || val < 0) break; if (time_after(jiffies, timeout)) break; } if (val == 0) { dev_err(qproc->dev, "MBA authentication of headers timed out\n"); ret = -ETIMEDOUT; goto out; } else if (val < 0) { dev_err(qproc->dev, "MBA returned error %d for segments\n", val); ret = -EINVAL; goto out; } ret = 0; out: return ret; }