blob: 16d1dd59dceb8fb2db2ff40e086da93d8f919131 [file] [log] [blame]
Lee Leahyb5ad8272015-04-20 15:29:16 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2015 Google Inc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Lee Leahyb5ad8272015-04-20 15:29:16 -070014 */
15
16#include <console/console.h>
17#include <cbmem.h>
Furquan Shaikhb0c2fe02016-05-09 12:23:01 -070018#include <commonlib/fsp.h>
Aaron Durbin789f2b62015-09-09 17:05:06 -050019#include <fsp/util.h>
Lee Leahyb5ad8272015-04-20 15:29:16 -070020
Aaron Durbin22ea0072015-08-05 10:17:33 -050021int fsp_relocate(struct prog *fsp_relocd, const struct region_device *fsp_src)
Lee Leahyb5ad8272015-04-20 15:29:16 -070022{
23 void *new_loc;
Aaron Durbin22ea0072015-08-05 10:17:33 -050024 void *fih;
Aaron Durbin8007c6b2015-09-10 21:19:25 -050025 ssize_t fih_offset;
Aaron Durbin22ea0072015-08-05 10:17:33 -050026 size_t size = region_device_sz(fsp_src);
Lee Leahyb5ad8272015-04-20 15:29:16 -070027
28 new_loc = cbmem_add(CBMEM_ID_REFCODE, size);
Aaron Durbin22ea0072015-08-05 10:17:33 -050029
Lee Leahyb5ad8272015-04-20 15:29:16 -070030 if (new_loc == NULL) {
Aaron Durbin22ea0072015-08-05 10:17:33 -050031 printk(BIOS_ERR, "ERROR: Unable to load FSP into memory.\n");
32 return -1;
Lee Leahyb5ad8272015-04-20 15:29:16 -070033 }
Aaron Durbin22ea0072015-08-05 10:17:33 -050034
35 if (rdev_readat(fsp_src, new_loc, 0, size) != size) {
36 printk(BIOS_ERR, "ERROR: Can't read FSP's region device.\n");
37 return -1;
38 }
39
Aaron Durbin8007c6b2015-09-10 21:19:25 -050040 fih_offset = fsp1_1_relocate((uintptr_t)new_loc, new_loc, size);
Aaron Durbin22ea0072015-08-05 10:17:33 -050041
Aaron Durbin8007c6b2015-09-10 21:19:25 -050042 if (fih_offset <= 0) {
Aaron Durbin22ea0072015-08-05 10:17:33 -050043 printk(BIOS_ERR, "ERROR: FSP relocation faiulre.\n");
44 return -1;
45 }
46
Aaron Durbina5be7fa2015-09-10 22:52:27 -050047 fih = (void *)((uint8_t *)new_loc + fih_offset);
Aaron Durbin8007c6b2015-09-10 21:19:25 -050048
Aaron Durbin22ea0072015-08-05 10:17:33 -050049 prog_set_area(fsp_relocd, new_loc, size);
50 prog_set_entry(fsp_relocd, fih, NULL);
51
52 return 0;
Lee Leahyb5ad8272015-04-20 15:29:16 -070053}