1
2
3
4
5
6
7#include <common.h>
8#include <dm.h>
9#include <init.h>
10#include <log.h>
11#include <spi_flash.h>
12#include <asm/fsp/fsp_support.h>
13#include <asm/fsp2/fsp_internal.h>
14#include <asm/global_data.h>
15
16
17#define PROBE_BUF_SIZE 0x180
18
19int fsp_get_header(ulong offset, ulong size, bool use_spi_flash,
20 struct fsp_header **fspp)
21{
22 static efi_guid_t guid = FSP_HEADER_GUID;
23 struct fv_ext_header *exhdr;
24 struct fsp_header *fsp;
25 struct ffs_file_header *file_hdr;
26 struct fv_header *fv;
27 struct raw_section *raw;
28 void *ptr, *base;
29 u8 buf[PROBE_BUF_SIZE];
30 struct udevice *dev;
31 int ret;
32
33
34
35
36
37
38
39
40 log_debug("offset=%x buf=%x, use_spi_flash=%d\n", (uint)offset,
41 (uint)buf, use_spi_flash);
42 if (use_spi_flash) {
43 ret = uclass_first_device_err(UCLASS_SPI_FLASH, &dev);
44 if (ret)
45 return log_msg_ret("Cannot find flash device", ret);
46 ret = spi_flash_read_dm(dev, offset, PROBE_BUF_SIZE, buf);
47 if (ret)
48 return log_msg_ret("Cannot read flash", ret);
49 } else {
50 memcpy(buf, (void *)offset, PROBE_BUF_SIZE);
51 }
52
53
54 ptr = buf;
55 fv = ptr;
56
57
58 log_debug("offset=%x sign=%x\n", (uint)offset, (uint)fv->sign);
59 if (fv->sign != EFI_FVH_SIGNATURE)
60 return log_msg_ret("Base FV signature", -EINVAL);
61
62
63 log_debug("fv->ext_hdr_off = %x\n", fv->ext_hdr_off);
64 ptr += fv->ext_hdr_off;
65 exhdr = ptr;
66 ptr += ALIGN(exhdr->ext_hdr_size, 8);
67 log_debug("ptr=%x\n", ptr - (void *)buf);
68
69
70 file_hdr = ptr;
71 if (memcmp(&file_hdr->name, &guid, sizeof(guid)))
72 return log_msg_ret("Base FFS GUID", -ENXIO);
73
74 ptr = file_hdr + 1;
75
76 raw = ptr;
77 log_debug("raw->type = %x\n", raw->type);
78 if (raw->type != EFI_SECTION_RAW)
79 return log_msg_ret("Section type not RAW", -ENOEXEC);
80
81
82 ptr = raw + 1;
83 fsp = ptr;
84
85
86 log_debug("fsp %x, fsp-buf=%x, si=%x\n", (uint)fsp, ptr - (void *)buf,
87 (void *)&fsp->fsp_silicon_init - (void *)buf);
88 if (fsp->sign != EFI_FSPH_SIGNATURE)
89 return log_msg_ret("Base FSPH signature", -EACCES);
90
91 base = (void *)fsp->img_base;
92 log_debug("image base %x\n", (uint)base);
93 if (fsp->fsp_mem_init)
94 log_debug("mem_init offset %x\n", (uint)fsp->fsp_mem_init);
95 else if (fsp->fsp_silicon_init)
96 log_debug("silicon_init offset %x\n",
97 (uint)fsp->fsp_silicon_init);
98 if (use_spi_flash) {
99 ret = spi_flash_read_dm(dev, offset, size, base);
100 if (ret)
101 return log_msg_ret("Could not read FPS-M", ret);
102 } else {
103 memcpy(base, (void *)offset, size);
104 }
105 ptr = base + (ptr - (void *)buf);
106 *fspp = ptr;
107
108 return 0;
109}
110
111u32 fsp_notify(struct fsp_header *fsp_hdr, u32 phase)
112{
113 fsp_notify_f notify;
114 struct fsp_notify_params params;
115 struct fsp_notify_params *params_ptr;
116 u32 status;
117
118 if (!ll_boot_init())
119 return 0;
120
121 if (!fsp_hdr)
122 fsp_hdr = gd->arch.fsp_s_hdr;
123
124 if (!fsp_hdr)
125 return log_msg_ret("no FSP", -ENOENT);
126
127 notify = (fsp_notify_f)(fsp_hdr->img_base + fsp_hdr->fsp_notify);
128 params.phase = phase;
129 params_ptr = ¶ms;
130
131
132
133
134
135 asm volatile (
136 "pushl %1;"
137 "call *%%eax;"
138 "addl $4, %%esp;"
139 : "=a"(status) : "m"(params_ptr), "a"(notify), "m"(*params_ptr)
140 );
141
142 return status;
143}
144