예제 #1
0
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);
}
예제 #2
0
파일: rmodule.c 프로젝트: AdriDlu/coreboot
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, &region_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;
}
예제 #3
0
static void rmodule_copy_payload(const struct rmodule *module)
{
	printk(BIOS_DEBUG, "Loading module at %p with entry %p. "
	       "filesize: 0x%x memsize: 0x%x\n",
	       module->location, rmodule_entry(module),
	       module->payload_size, rmodule_memory_size(module));

	/* No need to copy the payload if the load location and the
	 * payload location are the same. */
	if (module->location == module->payload)
		return;

	memcpy(module->location, module->payload, module->payload_size);
}
예제 #4
0
파일: rmodule.c 프로젝트: tidatida/coreboot
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, &region_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;
}