static secmon_entry_t secmon_load_rmodule(void) { struct rmodule secmon_mod; uint64_t secmon_base; size_t secmon_size; /* Get base address and size of the area available for secure monitor * rmodule. */ soc_get_secmon_base_size(&secmon_base, &secmon_size); if ((secmon_base == 0) || (secmon_size == 0)) { printk(BIOS_ERR, "ARM64: secmon_base / secmon_size invalid\n"); return NULL; } printk(BIOS_DEBUG,"secmon_base:%lx,secmon_size:%lx\n", (unsigned long)secmon_base, (unsigned long)secmon_size); /* Fail if can't parse secmon module */ if (rmodule_parse(&_binary_secmon_start, &secmon_mod)) { printk(BIOS_ERR, "ARM64: secmon_mod not found\n"); return NULL; } /* Load rmodule at secmon_base */ if (rmodule_load((void *)secmon_base, &secmon_mod)) { printk(BIOS_ERR, "ARM64:secmon_mod cannot load\n"); return NULL; } /* Identify the entry point for secure monitor */ return rmodule_entry(&secmon_mod); }
int rmodule_stage_load(struct rmod_stage_load *rsl) { struct rmodule rmod_stage; size_t region_size; char *stage_region; int rmodule_offset; int load_offset; struct cbfs_stage stage; void *rmod_loc; struct region_device *fh; if (rsl->prog == NULL || prog_name(rsl->prog) == NULL) return -1; fh = prog_rdev(rsl->prog); if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage)) return -1; rmodule_offset = rmodule_calc_region(DYN_CBMEM_ALIGN_SIZE, stage.memlen, ®ion_size, &load_offset); stage_region = cbmem_add(rsl->cbmem_id, region_size); if (stage_region == NULL) return -1; rmod_loc = &stage_region[rmodule_offset]; printk(BIOS_INFO, "Decompressing stage %s @ 0x%p (%d bytes)\n", prog_name(rsl->prog), rmod_loc, stage.memlen); if (!cbfs_load_and_decompress(fh, sizeof(stage), stage.len, rmod_loc, stage.memlen, stage.compression)) return -1; if (rmodule_parse(rmod_loc, &rmod_stage)) return -1; if (rmodule_load(&stage_region[load_offset], &rmod_stage)) return -1; prog_set_area(rsl->prog, rmod_stage.location, rmodule_memory_size(&rmod_stage)); prog_set_entry(rsl->prog, rmodule_entry(&rmod_stage), NULL); /* Allow caller to pick up parameters, if available. */ rsl->params = rmodule_parameters(&rmod_stage); return 0; }
int rmodule_stage_load(struct rmod_stage_load *rsl, struct cbfs_stage *stage) { struct rmodule rmod_stage; size_t region_size; char *stage_region; int rmodule_offset; int load_offset; if (stage == NULL || rsl->prog == NULL || rsl->prog->name == NULL) return -1; rmodule_offset = rmodule_calc_region(DYN_CBMEM_ALIGN_SIZE, stage->memlen, ®ion_size, &load_offset); stage_region = cbmem_add(rsl->cbmem_id, region_size); if (stage_region == NULL) return -1; printk(BIOS_INFO, "Decompressing stage %s @ 0x%p (%d bytes)\n", rsl->prog->name, &stage_region[rmodule_offset], stage->memlen); if (!cbfs_decompress(stage->compression, &stage[1], &stage_region[rmodule_offset], stage->len)) return -1; if (rmodule_parse(&stage_region[rmodule_offset], &rmod_stage)) return -1; if (rmodule_load(&stage_region[load_offset], &rmod_stage)) return -1; prog_set_area(rsl->prog, rmod_stage.location, rmodule_memory_size(&rmod_stage)); prog_set_entry(rsl->prog, rmodule_entry(&rmod_stage), NULL); return 0; }