void stage_cache_add(int stage_id, const struct prog *stage) { struct imd *imd; const struct imd_entry *e; struct stage_cache *meta; void *c; imd = imd_get(); e = imd_entry_add(imd, CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta)); if (e == NULL) { printk(BIOS_DEBUG, "Error: Can't add %x metadata to imd\n", CBMEM_ID_STAGEx_META + stage_id); return; } meta = imd_entry_at(imd, e); meta->load_addr = (uintptr_t)prog_start(stage); meta->entry_addr = (uintptr_t)prog_entry(stage); meta->arg = (uintptr_t)prog_entry_arg(stage); e = imd_entry_add(imd, CBMEM_ID_STAGEx_CACHE + stage_id, prog_size(stage)); if (e == NULL) { printk(BIOS_DEBUG, "Error: Can't add stage_cache %x to imd\n", CBMEM_ID_STAGEx_CACHE + stage_id); return; } c = imd_entry_at(imd, e); memcpy(c, prog_start(stage), prog_size(stage)); }
static void cache_refcode(const struct rmod_stage_load *rsl) { struct ramstage_cache *c; long cache_size; c = ramstage_cache_location(&cache_size); if (!ramstage_cache_is_valid(c)) { printk(BIOS_DEBUG, "No place to cache reference code.\n"); return; } /* Determine how much remaining cache available. */ cache_size -= c->size + sizeof(*c); if (cache_size < (sizeof(*c) + prog_size(rsl->prog))) { printk(BIOS_DEBUG, "Not enough cache space for ref code.\n"); return; } c = next_cache(c); c->magic = RAMSTAGE_CACHE_MAGIC; c->entry_point = (uint32_t)(uintptr_t)prog_entry(rsl->prog); c->load_address = (uint32_t)(uintptr_t)prog_start(rsl->prog); c->size = prog_size(rsl->prog); printk(BIOS_DEBUG, "Caching refcode at 0x%p(%x)\n", &c->program[0], c->size); memcpy(&c->program[0], (void *)c->load_address, c->size); }
void payload_load(void) { int i; const struct prog_loader_ops *ops; struct prog *payload = &global_payload; for (i = 0; i < ARRAY_SIZE(payload_ops); i++) { ops = payload_ops[i]; if (ops->prepare(payload) < 0) { printk(BIOS_DEBUG, "%s: could not locate payload.\n", ops->name); continue; } printk(BIOS_DEBUG, "%s: located payload @ %p, %zu bytes.\n", ops->name, prog_start(payload), prog_size(payload)); break; } if (i == ARRAY_SIZE(payload_ops)) goto out; mirror_payload(payload); /* Pass cbtables to payload if architecture desires it. */ prog_set_entry(payload, selfload(payload), cbmem_find(CBMEM_ID_CBTABLE)); out: if (prog_entry(payload) == NULL) die("Payload not loaded.\n"); }
/* Stage cache uses cbmem. */ void stage_cache_add(int stage_id, const struct prog *stage) { struct stage_cache *meta; void *c; meta = cbmem_add(CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta)); if (meta == NULL) return; meta->load_addr = (uintptr_t)prog_start(stage); meta->entry_addr = (uintptr_t)prog_entry(stage); c = cbmem_add(CBMEM_ID_STAGEx_CACHE + stage_id, prog_size(stage)); if (c == NULL) return; memcpy(c, prog_start(stage), prog_size(stage)); }
void finish_him(t_get *get, FD wr, t_label *lab) { lseek(wr, 0, SEEK_SET); my_put_in(COREWAR_EXEC_MAGIC, sizeof(int), wr); lseek(wr, sizeof(int) * 2 + PROG_NAME_LENGTH, SEEK_SET); my_put_in(prog_size(lab), sizeof(int), wr); lseek(wr, 0, SEEK_END); free_get(get); }
static void try_payload(struct prog *prog) { if (prog_type(prog) == PROG_PAYLOAD) { if (IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)) jmp_payload_no_bounce_buffer(prog_entry(prog)); else jmp_payload(prog_entry(prog), (uintptr_t)prog_start(prog), prog_size(prog)); } }
int prog_size(t_label *lab) { if (!lab) return (0); return (lab->size + prog_size(lab->next)); }