mb/google/brya/var/omnigul: Modify NVMe and UFS Storage support
[coreboot.git] / payloads / libpayload / libc / coreboot.c
blobbcc9530733bb14590a7b5a1c391dcbd3a9a92a19
1 /*
3 * Copyright (C) 2008 Advanced Micro Devices, Inc.
4 * Copyright (C) 2009 coresystems GmbH
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
30 #include <libpayload-config.h>
31 #include <libpayload.h>
32 #include <commonlib/bsd/cbmem_id.h>
33 #include <coreboot_tables.h>
34 #include <stdint.h>
37 * The code in this file applies to all coreboot architectures. Some coreboot
38 * table tags are architecture specific, they are handled by their respective
39 * cb_parse_arch_specific() functions.
42 /* === Parsing code === */
43 /* This is the generic parsing code. */
45 static void cb_parse_memory(void *ptr, struct sysinfo_t *info)
47 struct cb_memory *mem = ptr;
48 int count = MEM_RANGE_COUNT(mem);
49 int i;
51 if (count > SYSINFO_MAX_MEM_RANGES)
52 count = SYSINFO_MAX_MEM_RANGES;
54 info->n_memranges = 0;
56 for (i = 0; i < count; i++) {
57 struct cb_memory_range *range = MEM_RANGE_PTR(mem, i);
59 #if CONFIG(LP_MEMMAP_RAM_ONLY)
60 if (range->type != CB_MEM_RAM)
61 continue;
62 #endif
64 info->memrange[info->n_memranges].base = range->start;
65 info->memrange[info->n_memranges].size = range->size;
66 info->memrange[info->n_memranges].type = range->type;
68 info->n_memranges++;
72 static void cb_parse_serial(void *ptr, struct sysinfo_t *info)
74 info->cb_serial = virt_to_phys(ptr);
77 static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
79 struct lb_range *vbnv = (struct lb_range *)ptr;
81 info->vbnv_start = vbnv->range_start;
82 info->vbnv_size = vbnv->range_size;
85 static void cb_parse_mmc_info(unsigned char *ptr, struct sysinfo_t *info)
87 struct cb_mmc_info *mmc_info = (struct cb_mmc_info *)ptr;
89 info->mmc_early_wake_status = mmc_info->early_cmd1_status;
92 static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info)
94 int i;
95 struct cb_gpios *gpios = (struct cb_gpios *)ptr;
97 info->num_gpios = (gpios->count < SYSINFO_MAX_GPIOS) ?
98 (gpios->count) : SYSINFO_MAX_GPIOS;
100 for (i = 0; i < info->num_gpios; i++)
101 info->gpios[i] = gpios->gpios[i];
104 static void cb_parse_mac_addresses(unsigned char *ptr,
105 struct sysinfo_t *info)
107 struct cb_macs *macs = (struct cb_macs *)ptr;
108 int i;
110 info->num_macs = (macs->count < ARRAY_SIZE(info->macs)) ?
111 macs->count : ARRAY_SIZE(info->macs);
113 for (i = 0; i < info->num_macs; i++)
114 info->macs[i] = macs->mac_addrs[i];
117 static void cb_parse_board_config(unsigned char *ptr, struct sysinfo_t *info)
119 struct cb_board_config *const config = (struct cb_board_config *)ptr;
120 info->fw_config = config->fw_config;
121 info->board_id = config->board_id;
122 info->ram_code = config->ram_code;
123 info->sku_id = config->sku_id;
126 #if CONFIG(LP_NVRAM)
127 static void cb_parse_optiontable(void *ptr, struct sysinfo_t *info)
129 /* ptr is already virtual, but we want to keep physical addresses */
130 info->cmos_option_table = virt_to_phys(ptr);
133 static void cb_parse_checksum(void *ptr, struct sysinfo_t *info)
135 struct cb_cmos_checksum *cmos_cksum = ptr;
136 info->cmos_range_start = cmos_cksum->range_start;
137 info->cmos_range_end = cmos_cksum->range_end;
138 info->cmos_checksum_location = cmos_cksum->location;
140 #endif
142 #if CONFIG(LP_COREBOOT_VIDEO_CONSOLE)
143 static void cb_parse_framebuffer(void *ptr, struct sysinfo_t *info)
145 info->framebuffer = *(struct cb_framebuffer *)ptr;
147 #endif
149 static void cb_parse_string(const void *const ptr, uintptr_t *const info)
151 /* ptr is already virtual (str->string just an offset to that),
152 but we want to keep physical addresses */
153 const struct cb_string *const str = ptr;
154 *info = virt_to_phys(str->string);
157 static void cb_parse_ramoops(void *ptr, struct sysinfo_t *info)
159 struct lb_range *ramoops = (struct lb_range *)ptr;
161 info->ramoops_buffer = ramoops->range_start;
162 info->ramoops_buffer_size = ramoops->range_size;
165 static void cb_parse_mtc(void *ptr, struct sysinfo_t *info)
167 struct lb_range *mtc = (struct lb_range *)ptr;
169 info->mtc_start = mtc->range_start;
170 info->mtc_size = mtc->range_size;
173 static void cb_parse_spi_flash(void *ptr, struct sysinfo_t *info)
175 struct cb_spi_flash *flash = (struct cb_spi_flash *)ptr;
177 info->spi_flash.size = flash->flash_size;
178 info->spi_flash.sector_size = flash->sector_size;
179 info->spi_flash.erase_cmd = flash->erase_cmd;
181 if (flash->mmap_count == 0)
182 return;
184 info->spi_flash.mmap_window_count = MIN(flash->mmap_count, SYSINFO_MAX_MMAP_WINDOWS);
185 memcpy(info->spi_flash.mmap_table, flash->mmap_table,
186 info->spi_flash.mmap_window_count * sizeof(struct flash_mmap_window));
189 static void cb_parse_boot_media_params(unsigned char *ptr,
190 struct sysinfo_t *info)
192 struct cb_boot_media_params *const bmp =
193 (struct cb_boot_media_params *)ptr;
194 info->fmap_offset = bmp->fmap_offset;
195 info->cbfs_offset = bmp->cbfs_offset;
196 info->cbfs_size = bmp->cbfs_size;
197 info->boot_media_size = bmp->boot_media_size;
200 #if CONFIG(LP_TIMER_RDTSC)
201 static void cb_parse_tsc_info(void *ptr, struct sysinfo_t *info)
203 const struct cb_tsc_info *tsc_info = ptr;
205 if (tsc_info->freq_khz == 0)
206 return;
208 /* Honor the TSC frequency passed to the payload. */
209 info->cpu_khz = tsc_info->freq_khz;
211 #endif
213 static void cb_parse_cbmem_entry(void *ptr, struct sysinfo_t *info)
215 const struct cb_cbmem_entry *cbmem_entry = ptr;
217 if (cbmem_entry->size != sizeof(*cbmem_entry))
218 return;
220 switch (cbmem_entry->id) {
221 case CBMEM_ID_ACPI_CNVS:
222 info->acpi_cnvs = cbmem_entry->address;
223 break;
224 case CBMEM_ID_ACPI_GNVS:
225 info->acpi_gnvs = cbmem_entry->address;
226 break;
227 case CBMEM_ID_CBFS_RO_MCACHE:
228 info->cbfs_ro_mcache_offset = cbmem_entry->address;
229 info->cbfs_ro_mcache_size = cbmem_entry->entry_size;
230 break;
231 case CBMEM_ID_CBFS_RW_MCACHE:
232 info->cbfs_rw_mcache_offset = cbmem_entry->address;
233 info->cbfs_rw_mcache_size = cbmem_entry->entry_size;
234 break;
235 case CBMEM_ID_CONSOLE:
236 info->cbmem_cons = cbmem_entry->address;
237 break;
238 case CBMEM_ID_MRCDATA:
239 info->mrc_cache = cbmem_entry->address;
240 break;
241 case CBMEM_ID_VBOOT_WORKBUF:
242 info->vboot_workbuf = cbmem_entry->address;
243 break;
244 case CBMEM_ID_TIMESTAMP:
245 info->tstamp_table = cbmem_entry->address;
246 break;
247 case CBMEM_ID_VPD:
248 info->chromeos_vpd = cbmem_entry->address;
249 break;
250 case CBMEM_ID_FMAP:
251 info->fmap_cache = cbmem_entry->address;
252 break;
253 case CBMEM_ID_WIFI_CALIBRATION:
254 info->wifi_calibration = cbmem_entry->address;
255 break;
256 case CBMEM_ID_TYPE_C_INFO:
257 info->type_c_info = cbmem_entry->address;
258 break;
259 case CBMEM_ID_MEM_CHIP_INFO:
260 info->mem_chip_base = cbmem_entry->address;
261 break;
262 default:
263 break;
267 static void cb_parse_pcie(void *ptr, struct sysinfo_t *info)
269 const struct cb_pcie *pcie = ptr;
271 info->pcie_ctrl_base = pcie->ctrl_base;
274 static void cb_parse_rsdp(void *ptr, struct sysinfo_t *info)
276 const struct cb_acpi_rsdp *cb_acpi_rsdp = ptr;
277 info->acpi_rsdp = cb_acpi_rsdp->rsdp_pointer;
280 int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
282 struct cb_header *header;
283 unsigned char *ptr = addr;
284 void *forward;
285 int i;
287 for (i = 0; i < len; i += 16, ptr += 16) {
288 header = (struct cb_header *)ptr;
289 if (!strncmp((const char *)header->signature, "LBIO", 4))
290 break;
293 /* We walked the entire space and didn't find anything. */
294 if (i >= len)
295 return -1;
297 /* Make sure the checksums match. */
298 if (ipchksum((u16 *) header, sizeof(*header)) != 0)
299 return -1;
301 if (!header->table_bytes)
302 return 0;
304 if (ipchksum((u16 *) (ptr + sizeof(*header)),
305 header->table_bytes) != header->table_checksum)
306 return -1;
308 info->cb_header = virt_to_phys(header);
310 /* Initialize IDs as undefined in case they don't show up in table. */
311 info->board_id = UNDEFINED_STRAPPING_ID;
312 info->ram_code = UNDEFINED_STRAPPING_ID;
313 info->sku_id = UNDEFINED_STRAPPING_ID;
314 info->fw_config = UNDEFINED_FW_CONFIG;
316 /* Now, walk the tables. */
317 ptr += header->header_bytes;
319 for (i = 0; i < header->table_entries; i++) {
320 struct cb_record *rec = (struct cb_record *)ptr;
322 /* We only care about a few tags here (maybe more later). */
323 switch (rec->tag) {
324 case CB_TAG_FORWARD:
325 forward = phys_to_virt((void *)(unsigned long)
326 ((struct cb_forward *)rec)->forward);
327 return cb_parse_header(forward, len, info);
328 case CB_TAG_MEMORY:
329 cb_parse_memory(ptr, info);
330 break;
331 case CB_TAG_SERIAL:
332 cb_parse_serial(ptr, info);
333 break;
334 case CB_TAG_VERSION:
335 cb_parse_string(ptr, &info->cb_version);
336 break;
337 case CB_TAG_EXTRA_VERSION:
338 cb_parse_string(ptr, &info->extra_version);
339 break;
340 case CB_TAG_BUILD:
341 cb_parse_string(ptr, &info->build);
342 break;
343 case CB_TAG_COMPILE_TIME:
344 cb_parse_string(ptr, &info->compile_time);
345 break;
346 case CB_TAG_COMPILE_BY:
347 cb_parse_string(ptr, &info->compile_by);
348 break;
349 case CB_TAG_COMPILE_HOST:
350 cb_parse_string(ptr, &info->compile_host);
351 break;
352 case CB_TAG_COMPILE_DOMAIN:
353 cb_parse_string(ptr, &info->compile_domain);
354 break;
355 case CB_TAG_COMPILER:
356 cb_parse_string(ptr, &info->compiler);
357 break;
358 case CB_TAG_LINKER:
359 cb_parse_string(ptr, &info->linker);
360 break;
361 case CB_TAG_ASSEMBLER:
362 cb_parse_string(ptr, &info->assembler);
363 break;
364 #if CONFIG(LP_NVRAM)
365 case CB_TAG_CMOS_OPTION_TABLE:
366 cb_parse_optiontable(ptr, info);
367 break;
368 case CB_TAG_OPTION_CHECKSUM:
369 cb_parse_checksum(ptr, info);
370 break;
371 #endif
372 #if CONFIG(LP_COREBOOT_VIDEO_CONSOLE)
373 // FIXME we should warn on serial if coreboot set up a
374 // framebuffer buf the payload does not know about it.
375 case CB_TAG_FRAMEBUFFER:
376 cb_parse_framebuffer(ptr, info);
377 break;
378 #endif
379 case CB_TAG_MAINBOARD:
380 info->cb_mainboard = virt_to_phys(ptr);
381 break;
382 case CB_TAG_GPIO:
383 cb_parse_gpios(ptr, info);
384 break;
385 case CB_TAG_VBNV:
386 cb_parse_vbnv(ptr, info);
387 break;
388 case CB_TAG_MAC_ADDRS:
389 cb_parse_mac_addresses(ptr, info);
390 break;
391 case CB_TAG_SERIALNO:
392 cb_parse_string(ptr, &info->serialno);
393 break;
394 case CB_TAG_BOARD_CONFIG:
395 cb_parse_board_config(ptr, info);
396 break;
397 case CB_TAG_RAM_OOPS:
398 cb_parse_ramoops(ptr, info);
399 break;
400 case CB_TAG_SPI_FLASH:
401 cb_parse_spi_flash(ptr, info);
402 break;
403 case CB_TAG_MMC_INFO:
404 cb_parse_mmc_info(ptr, info);
405 break;
406 case CB_TAG_MTC:
407 cb_parse_mtc(ptr, info);
408 break;
409 case CB_TAG_BOOT_MEDIA_PARAMS:
410 cb_parse_boot_media_params(ptr, info);
411 break;
412 case CB_TAG_CBMEM_ENTRY:
413 cb_parse_cbmem_entry(ptr, info);
414 break;
415 #if CONFIG(LP_TIMER_RDTSC)
416 case CB_TAG_TSC_INFO:
417 cb_parse_tsc_info(ptr, info);
418 break;
419 #endif
420 case CB_TAG_ACPI_RSDP:
421 cb_parse_rsdp(ptr, info);
422 break;
423 case CB_TAG_PCIE:
424 cb_parse_pcie(ptr, info);
425 break;
426 default:
427 cb_parse_arch_specific(rec, info);
428 break;
431 ptr += rec->size;
434 return 0;