1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <boot_device.h>
4 #include <commonlib/region.h>
5 #include <console/console.h>
7 #include <intelblocks/fast_spi.h>
11 * 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
26 * bios_start +---> +--------+------------------> +-----------+ 4GiB - bios_size
29 * | | | bios_mapped_size | BIOS |
33 * | | +------------------> +-----------+ 4GiB - 256KiB
36 * bios_end +---> +--------+ +-----------+ 4GiB
43 static size_t bios_size
;
45 static struct region_device shadow_dev
;
46 static struct xlate_region_device real_dev
;
47 static struct xlate_window real_dev_window
;
49 static void bios_mmap_init(void)
51 size_t size
, start
, bios_mapped_size
;
56 /* If bios_size is initialized, then bail out. */
59 start
= fast_spi_get_bios_region(&size
);
61 /* BIOS region is mapped right below 4G. */
62 base
= 4ULL * GiB
- size
;
65 * The 256 KiB right below 4G are decoded by readonly SRAM,
68 bios_mapped_size
= size
- 256 * KiB
;
70 rdev_chain_mem(&shadow_dev
, (void *)base
, bios_mapped_size
);
72 xlate_window_init(&real_dev_window
, &shadow_dev
, start
, bios_mapped_size
);
73 xlate_region_device_ro_init(&real_dev
, 1, &real_dev_window
, CONFIG_ROM_SIZE
);
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
) &&
81 !region_is_subregion(&real_dev_window
.sub_region
, &cbfs_region
))
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
);
88 const struct region_device
*boot_device_ro(void)
92 return &real_dev
.rdev
;
95 uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window
*table
)
99 table
->flash_base
= region_offset(&real_dev_window
.sub_region
);
100 table
->host_base
= (uintptr_t)rdev_mmap_full(&shadow_dev
);
101 table
->size
= region_sz(&real_dev_window
.sub_region
);