/* Pack the device_tree and place it at given position. */ static void pack_fdt(struct region *fdt, struct device_tree *dt) { printk(BIOS_INFO, "FIT: Flattening FDT to %p\n", (void *)fdt->offset); dt_flatten(dt, (void *)fdt->offset); prog_segment_loaded(fdt->offset, fdt->size, 0); }
void fsps_load(bool s3wake) { struct fsp_header *hdr = &fsps_hdr; struct cbfsf file_desc; struct region_device rdev; const char *name = CONFIG_FSP_S_CBFS; void *dest; size_t size; struct prog fsps = PROG_INIT(PROG_REFCODE, name); static int load_done; if (load_done) return; if (s3wake && !IS_ENABLED(CONFIG_NO_STAGE_CACHE)) { printk(BIOS_DEBUG, "Loading FSPS from stage_cache\n"); stage_cache_load_stage(STAGE_REFCODE, &fsps); if (fsp_validate_component(hdr, prog_rdev(&fsps)) != CB_SUCCESS) die("On resume fsps header is invalid\n"); load_done = 1; return; } if (cbfs_boot_locate(&file_desc, name, NULL)) { printk(BIOS_ERR, "Could not locate %s in CBFS\n", name); die("FSPS not available!\n"); } cbfs_file_data(&rdev, &file_desc); /* Load and relocate into CBMEM. */ size = region_device_sz(&rdev); dest = cbmem_add(CBMEM_ID_REFCODE, size); if (dest == NULL) die("Could not add FSPS to CBMEM!\n"); if (rdev_readat(&rdev, dest, 0, size) < 0) die("Failed to read FSPS!\n"); if (fsp_component_relocate((uintptr_t)dest, dest, size) < 0) die("Unable to relocate FSPS!\n"); /* Create new region device in memory after relocation. */ rdev_chain(&rdev, &addrspace_32bit.rdev, (uintptr_t)dest, size); if (fsp_validate_component(hdr, &rdev) != CB_SUCCESS) die("Invalid FSPS header!\n"); prog_set_area(&fsps, dest, size); stage_cache_add(STAGE_REFCODE, &fsps); /* Signal that FSP component has been loaded. */ prog_segment_loaded(hdr->image_base, hdr->image_size, SEG_FINAL); load_done = 1; }
/** * Extract a node to given regions. * Returns true on error, false on success. */ static bool extract(struct region *region, struct fit_image_node *node) { void *dst = (void *)region->offset; const char *comp_name; size_t true_size = 0; switch (node->compression) { case CBFS_COMPRESS_NONE: comp_name = "Relocating uncompressed"; break; case CBFS_COMPRESS_LZMA: comp_name = "Decompressing LZMA"; break; case CBFS_COMPRESS_LZ4: comp_name = "Decompressing LZ4"; break; default: printk(BIOS_ERR, "ERROR: Unsupported compression\n"); return true; } printk(BIOS_INFO, "FIT: %s %s to %p\n", comp_name, node->name, dst); switch (node->compression) { case CBFS_COMPRESS_NONE: memcpy(dst, node->data, node->size); true_size = node->size; break; case CBFS_COMPRESS_LZMA: timestamp_add_now(TS_START_ULZMA); true_size = ulzman(node->data, node->size, dst, region->size); timestamp_add_now(TS_END_ULZMA); break; case CBFS_COMPRESS_LZ4: timestamp_add_now(TS_START_ULZ4F); true_size = ulz4fn(node->data, node->size, dst, region->size); timestamp_add_now(TS_END_ULZ4F); break; default: return true; } if (!true_size) { printk(BIOS_ERR, "ERROR: %s node failed!\n", comp_name); return true; } prog_segment_loaded(region->offset, true_size, 0); return false; }
enum fsp_status fsp_silicon_init(void) { struct fsp_header *hdr = &fsps_hdr; struct cbfsf file_desc; struct region_device rdev; const char *name = CONFIG_FSP_S_CBFS; void *dest; size_t size; if (cbfs_boot_locate(&file_desc, name, NULL)) { printk(BIOS_ERR, "Could not locate %s in CBFS\n", name); return FSP_NOT_FOUND; } cbfs_file_data(&rdev, &file_desc); /* Load and relocate into CBMEM. */ size = region_device_sz(&rdev); dest = cbmem_add(CBMEM_ID_REFCODE, size); if (dest == NULL) { printk(BIOS_ERR, "Could not add FSPS to CBMEM.\n"); return FSP_NOT_FOUND; } if (rdev_readat(&rdev, dest, 0, size) < 0) return FSP_NOT_FOUND; if (fsp_component_relocate((uintptr_t)dest, dest, size) < 0) { printk(BIOS_ERR, "Unable to relocate FSPS.\n"); return FSP_NOT_FOUND; } /* Create new region device in memory after relocation. */ rdev_chain(&rdev, &addrspace_32bit.rdev, (uintptr_t)dest, size); if (fsp_validate_component(hdr, &rdev) != CB_SUCCESS) return FSP_NOT_FOUND; /* Signal that FSP component has been loaded. */ prog_segment_loaded(hdr->image_base, hdr->image_size, SEG_FINAL); return do_silicon_init(hdr); }
int rmodule_load(void *base, struct rmodule *module) { /* * In order to load the module at a given address, the following steps * take place: * 1. Copy payload to base address. * 2. Adjust relocations within the module to new base address. * 3. Clear the bss segment last since the relocations live where * the bss is. If an rmodule is being loaded from its load * address the relocations need to be processed before the bss. */ module->location = base; rmodule_copy_payload(module); if (rmodule_relocate(module)) return -1; rmodule_clear_bss(module); prog_segment_loaded((uintptr_t)module->location, rmodule_memory_size(module), SEG_FINAL); return 0; }
void fsp_memory_init(bool s3wake) { struct fsp_header hdr; enum cb_err status; struct cbfsf file_desc; struct region_device file_data; const char *name = CONFIG_FSP_M_CBFS; struct memranges memmap; struct range_entry freeranges[2]; if (CONFIG(ELOG_BOOT_COUNT) && !s3wake) boot_count_increment(); if (cbfs_boot_locate(&file_desc, name, NULL)) { printk(BIOS_CRIT, "Could not locate %s in CBFS\n", name); die("FSPM not available!\n"); } cbfs_file_data(&file_data, &file_desc); /* Build up memory map of romstage address space including CAR. */ memranges_init_empty(&memmap, &freeranges[0], ARRAY_SIZE(freeranges)); memranges_insert(&memmap, (uintptr_t)_car_region_start, _car_relocatable_data_end - _car_region_start, 0); memranges_insert(&memmap, (uintptr_t)_program, REGION_SIZE(program), 0); if (!CONFIG(FSP_M_XIP)) status = load_fspm_mem(&hdr, &file_data, &memmap); else status = load_fspm_xip(&hdr, &file_data); if (status != CB_SUCCESS) die("Loading FSPM failed!\n"); /* Signal that FSP component has been loaded. */ prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL); do_fsp_memory_init(&hdr, s3wake, &memmap); }