blob: 6e0800cd653c25b52654b74bc0686900bd356e82 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Andrey Petrov5672dcd2016-02-12 15:12:43 -08002
3#include <boot_device.h>
Andrey Petrov5672dcd2016-02-12 15:12:43 -08004#include <commonlib/region.h>
5#include <console/console.h>
6#include <fmap.h>
Barnali Sarkare70142c2017-03-28 16:32:33 +05307#include <intelblocks/fast_spi.h>
Furquan Shaikh493937e2020-11-25 17:15:09 -08008#include <spi_flash.h>
Andrey Petrov5672dcd2016-02-12 15:12:43 -08009
10/*
Furquan Shaikh0be3da52016-06-19 23:20:43 -070011 * BIOS region on the flash is mapped right below 4GiB in the address
12 * space. However, 256KiB right below 4GiB is decoded by read-only SRAM and not
13 * boot media.
14 *
Lee Leahy07441b52017-03-09 10:59:25 -080015 * +-----------+ 0
16 * | |
17 * | |
18 * | |
19 * | |
20 * | |
21 * | |
22 * | |
23 * | |
24 * +--------+ | |
25 * | IFD | | |
26 * bios_start +---> +--------+------------------> +-----------+ 4GiB - bios_size
27 * ^ | | ^ | |
28 * | | | | | |
29 * | | | bios_mapped_size | BIOS |
30 * | | BIOS | | | |
31 * bios_size | | | | |
32 * | | | v | |
33 * | | +------------------> +-----------+ 4GiB - 256KiB
34 * | | | | Read only |
35 * v | | | SRAM |
36 * bios_end +---> +--------+ +-----------+ 4GiB
37 * | Device |
38 * | ext |
39 * +--------+
Furquan Shaikh0be3da52016-06-19 23:20:43 -070040 *
Andrey Petrov5672dcd2016-02-12 15:12:43 -080041 */
Andrey Petrov5672dcd2016-02-12 15:12:43 -080042
Arthur Heymans6d6945b2018-12-29 14:00:46 +010043static size_t bios_size;
Andrey Petrov5672dcd2016-02-12 15:12:43 -080044
Julius Wernerc8931972021-04-16 16:48:32 -070045static struct region_device shadow_dev;
Arthur Heymans6d6945b2018-12-29 14:00:46 +010046static struct xlate_region_device real_dev;
Furquan Shaikhf5b30ed2020-11-11 23:23:13 -080047static struct xlate_window real_dev_window;
Furquan Shaikh0be3da52016-06-19 23:20:43 -070048
49static void bios_mmap_init(void)
50{
Barnali Sarkare70142c2017-03-28 16:32:33 +053051 size_t size, start, bios_mapped_size;
Subrata Banikc7908502017-03-23 11:52:59 +053052 uintptr_t base;
Furquan Shaikh0be3da52016-06-19 23:20:43 -070053
Arthur Heymans6d6945b2018-12-29 14:00:46 +010054 size = bios_size;
Furquan Shaikh0be3da52016-06-19 23:20:43 -070055
56 /* If bios_size is initialized, then bail out. */
57 if (size != 0)
58 return;
Barnali Sarkare70142c2017-03-28 16:32:33 +053059 start = fast_spi_get_bios_region(&size);
Furquan Shaikh0be3da52016-06-19 23:20:43 -070060
Furquan Shaikh0be3da52016-06-19 23:20:43 -070061 /* BIOS region is mapped right below 4G. */
62 base = 4ULL * GiB - size;
63
64 /*
65 * The 256 KiB right below 4G are decoded by readonly SRAM,
66 * not boot media.
67 */
68 bios_mapped_size = size - 256 * KiB;
69
Julius Wernerc8931972021-04-16 16:48:32 -070070 rdev_chain_mem(&shadow_dev, (void *)base, bios_mapped_size);
Furquan Shaikh0be3da52016-06-19 23:20:43 -070071
Julius Wernerc8931972021-04-16 16:48:32 -070072 xlate_window_init(&real_dev_window, &shadow_dev, start, bios_mapped_size);
Furquan Shaikhf5b30ed2020-11-11 23:23:13 -080073 xlate_region_device_ro_init(&real_dev, 1, &real_dev_window, CONFIG_ROM_SIZE);
Furquan Shaikh0be3da52016-06-19 23:20:43 -070074
Arthur Heymans6d6945b2018-12-29 14:00:46 +010075 bios_size = size;
Julius Werner029d6722019-12-05 22:08:09 -080076
77 /* Check that the CBFS lies within the memory mapped area. It's too
78 easy to forget the SRAM mapping when crafting an FMAP file. */
79 struct region cbfs_region;
80 if (!fmap_locate_area("COREBOOT", &cbfs_region) &&
Furquan Shaikhf5b30ed2020-11-11 23:23:13 -080081 !region_is_subregion(&real_dev_window.sub_region, &cbfs_region))
Julius Werner029d6722019-12-05 22:08:09 -080082 printk(BIOS_CRIT,
83 "ERROR: CBFS @ %zx size %zx exceeds mem-mapped area @ %zx size %zx\n",
84 region_offset(&cbfs_region), region_sz(&cbfs_region),
85 start, bios_mapped_size);
Furquan Shaikh0be3da52016-06-19 23:20:43 -070086}
Andrey Petrov5672dcd2016-02-12 15:12:43 -080087
88const struct region_device *boot_device_ro(void)
89{
Furquan Shaikh0be3da52016-06-19 23:20:43 -070090 bios_mmap_init();
91
Arthur Heymans6d6945b2018-12-29 14:00:46 +010092 return &real_dev.rdev;
Andrey Petrov5672dcd2016-02-12 15:12:43 -080093}
Furquan Shaikh493937e2020-11-25 17:15:09 -080094
95uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
96{
97 bios_mmap_init();
98
99 table->flash_base = region_offset(&real_dev_window.sub_region);
Julius Wernerc8931972021-04-16 16:48:32 -0700100 table->host_base = (uintptr_t)rdev_mmap_full(&shadow_dev);
Furquan Shaikh493937e2020-11-25 17:15:09 -0800101 table->size = region_sz(&real_dev_window.sub_region);
102
103 return 1;
104}