/* Wait for GSP access via BAR0 to be allowed. */
*mbox0 = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_MAILBOX0);
if (*mbox0 && (*mbox0 & 0xffffff00) == 0xbadf4100) returnfalse;
/* Check if an error code has been reported. */ if (*mbox0) {
u32 mbox1 = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_MAILBOX1);
/* Any value that's not GSP_FMC_BOOT_PARAMS addr is an error. */ if ((((u64)mbox1 << 32) | *mbox0) != gsp->fmc.args.addr) returntrue;
}
/* Check if lockdown has been released. */
data = nvkm_falcon_rd32(&gsp->falcon, NV_PFALCON_FALCON_HWCFG2); return !NVVAL_GET(data, NV_PFALCON, FALCON_HWCFG2, RISCV_BR_PRIV_LOCKDOWN);
}
/** * elf_validate_sections - validate each section in the FMC ELF image * @elf: ELF image * @length: size of the entire ELF image
*/ staticbool
elf_validate_sections(constvoid *elf, size_t length)
{ conststruct elf32_hdr *ehdr = elf; conststruct elf32_shdr *shdr = elf + ehdr->e_shoff;
/* The offset of the first section */
Elf32_Off section_begin = ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize;
if (section_begin > length) returnfalse;
/* The first section header is the null section, so skip it */ for (unsignedint i = 1; i < ehdr->e_shnum; i++) { if (i == ehdr->e_shstrndx) { if (shdr[i].sh_type != SHT_STRTAB) returnfalse; if (shdr[i].sh_flags != SHF_STRINGS) returnfalse;
} else { if (shdr[i].sh_type != SHT_PROGBITS) returnfalse; if (shdr[i].sh_flags != FMC_SHF_FLAGS) returnfalse;
}
/* Ensure that each section is inside the image */ if (shdr[i].sh_offset < section_begin ||
(u64)shdr[i].sh_offset + shdr[i].sh_size > length) returnfalse;
/* Non-zero sh_info is a CRC */ if (shdr[i].sh_info) { /* The kernel's CRC32 needs a pre- and post-xor to match standard CRCs */
u32 crc32 = crc32_le(~0, elf + shdr[i].sh_offset, shdr[i].sh_size) ^ ~0;
if (shdr[i].sh_info != crc32) returnfalse;
}
}
returntrue;
}
/** * elf_section - return a pointer to the data for a given section * @elf: ELF image * @name: section name to search for * @len: pointer to returned length of found section
*/ staticconstvoid *
elf_section(constvoid *elf, constchar *name, unsignedint *len)
{ conststruct elf32_hdr *ehdr = elf; conststruct elf32_shdr *shdr = elf + ehdr->e_shoff; constchar *names = elf + shdr[ehdr->e_shstrndx].sh_offset;
for (unsignedint i = 1; i < ehdr->e_shnum; i++) { if (!strcmp(&names[shdr[i].sh_name], name)) {
*len = shdr[i].sh_size; return elf + shdr[i].sh_offset;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.