coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mmap_boot.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 /*
4  * This file provides a custom boot media device for the platforms that support additional
5  * window for BIOS regions greater than 16MiB. If the mainboard uses a smaller BIOS region, then
6  * the additional window is unused.
7  */
8 
9 #include <boot_device.h>
10 #include <commonlib/region.h>
11 #include <console/console.h>
12 #include <fmap.h>
13 #include <intelblocks/fast_spi.h>
14 #include <spi_flash.h>
15 
17  /* Fixed decode window of max 16MiB size just below 4G boundary */
19  /* Additional decode window for mapping BIOS region greater than 16MiB */
22 };
23 
24 static struct xlate_region_device real_dev;
27 
28 static void initialize_window(enum window_type type, uintptr_t host_base,
29  uintptr_t flash_base, size_t size)
30 {
31  mem_region_device_ro_init(&shadow_devs[type], (void *)host_base, size);
33  flash_base, size);
34  printk(BIOS_INFO, "MMAP window: SPI flash base=0x%lx, Host base=0x%lx, Size=0x%zx\n",
35  flash_base, host_base, size);
36 }
37 
38 /*
39  *
40  * +--------------+
41  * | |
42  * | |
43  * | |
44  * ^ +------------+--------------------------^--------------------------------+ 0xffffffff
45  * | | | | | |
46  * | | | | | |
47  * | | | + | FIXED |
48  * | | | fixed_win_size | DECODE |
49  * | | BIOS | + | WINDOW |
50  * + | region | | | |
51  * bios_size | (Region 1) | | | |
52  * + | | | | |
53  * | | | | | |
54  * | | | fixed_win_flash_base+----v--------------------------------+ fixed_win_host_base
55  * | | | | | |
56  * | | | | | |
57  * | | | | | Other MMIO |
58  * v | | | | |
59  * bios_start +------------+ ext_win_flash_base | | |
60  * | | + | | |
61  * | | | | | |
62  * | | | | | |
63  * | | | +-----^------------------------------------------------------------^
64  * 0 +------------+ | | | | |
65  * | + | EXT_BIOS | |
66  * SPI flash | ext_win_size | DECODE | |
67  * address | + | WINDOW | +
68  * space | | | | CONFIG_EXT_BIOS_WIN_SIZE
69  * +--------------v-------------------------------+ ext_win_host_base +
70  * | | |
71  * | Unused | |
72  * | | |
73  * +--------------+ CONFIG_EXT_BIOS_WIN_BASE+--v
74  * | |
75  * | |
76  * | |
77  * +--------------+
78  *
79  * Host address
80  * space
81  */
82 static void bios_mmap_init(void)
83 {
84  static bool init_done;
85 
86  size_t bios_size, bios_start;
87 
88  uintptr_t fixed_win_host_base, fixed_win_flash_base;
89  uintptr_t ext_win_host_base, ext_win_flash_base;
90  size_t fixed_win_size, ext_win_size;
91 
92  size_t win_count = 0;
93 
94  if (init_done)
95  return;
96 
97  /* Read the offset and size of BIOS region in the SPI flash address space. */
98  bios_start = fast_spi_get_bios_region(&bios_size);
99 
100  /*
101  * By default, fixed decode window (maximum size 16MiB) is mapped just below the 4G
102  * boundary. This window maps the top part of the BIOS region in the SPI flash address
103  * space to the host address space.
104  */
105  fixed_win_size = MIN(16 * MiB, bios_size);
106  fixed_win_host_base = 4ULL * GiB - fixed_win_size;
107  fixed_win_flash_base = bios_start + bios_size - fixed_win_size;
108 
109  initialize_window(FIXED_DECODE_WINDOW, fixed_win_host_base, fixed_win_flash_base,
110  fixed_win_size);
111  win_count++;
112 
113  _Static_assert(CONFIG_EXT_BIOS_WIN_BASE != 0, "Extended BIOS window base cannot be 0!");
114  _Static_assert(CONFIG_EXT_BIOS_WIN_SIZE != 0, "Extended BIOS window size cannot be 0!");
115 
116  /*
117  * Remaining portion of the BIOS region up to a maximum of CONFIG_EXT_BIOS_WIN_SIZE is
118  * mapped at the top of the extended window if the BIOS region is greater than 16MiB.
119  *
120  * If the BIOS region is not greater than 16MiB, then the extended window is not
121  * enabled.
122  */
123  ext_win_size = MIN(CONFIG_EXT_BIOS_WIN_SIZE, bios_size - fixed_win_size);
124 
125  if (ext_win_size) {
126  ext_win_host_base = CONFIG_EXT_BIOS_WIN_BASE + CONFIG_EXT_BIOS_WIN_SIZE -
127  ext_win_size;
128  ext_win_flash_base = fixed_win_flash_base - ext_win_size;
129  initialize_window(EXT_BIOS_DECODE_WINDOW, ext_win_host_base,
130  ext_win_flash_base, ext_win_size);
131  win_count++;
132  }
133 
134  xlate_region_device_ro_init(&real_dev, win_count, real_dev_windows, CONFIG_ROM_SIZE);
135 
136  init_done = true;
137 }
138 
139 const struct region_device *boot_device_ro(void)
140 {
141  bios_mmap_init();
142 
143  return &real_dev.rdev;
144 }
145 
147 {
149 
150  bios_mmap_init();
151 
152  *size = region_device_sz(rd);
153 
154  if (*size == 0) {
155  *base = 0;
156  } else {
157  /*
158  * This is a memory region device. So, mmap returns the base address of the
159  * device. Also, as this is a memory region device, unmap is a no-op.
160  */
161  *base = (uintptr_t)rdev_mmap_full(rd);
162  }
163 }
164 
166 {
167  int i;
168  uint32_t count = 0;
169 
170  bios_mmap_init();
171 
172  for (i = 0; i < TOTAL_DECODE_WINDOWS; i++) {
173 
174  if (region_sz(&real_dev_windows[i].sub_region) == 0)
175  continue;
176 
177  count++;
178  table->flash_base = region_offset(&real_dev_windows[i].sub_region);
180  table->size = region_sz(&real_dev_windows[i].sub_region);
181 
182  table++;
183  }
184 
185  return count;
186 }
uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
Definition: mmap_boot.c:18
const struct region_device * boot_device_ro(void)
Definition: mmap_boot.c:13
#define MIN(a, b)
Definition: helpers.h:37
#define MiB
Definition: helpers.h:76
#define GiB
Definition: helpers.h:77
#define printk(level,...)
Definition: stdlib.h:16
size_t fast_spi_get_bios_region(size_t *bios_size)
Definition: fast_spi.c:232
static struct region_device rdev
Definition: flashconsole.c:14
unsigned int type
Definition: edid.c:57
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
_Static_assert(sizeof(hls_t)==HLS_SIZE, "HLS_SIZE must equal to sizeof(hls_t)")
static size_t region_sz(const struct region *r)
Definition: region.h:110
static size_t region_device_sz(const struct region_device *rdev)
Definition: region.h:132
void xlate_window_init(struct xlate_window *window, const struct region_device *access_dev, size_t sub_region_offset, size_t sub_region_size)
Definition: region.c:216
void mem_region_device_ro_init(struct mem_region_device *mdev, void *base, size_t size)
Definition: region.c:166
static void * rdev_mmap_full(const struct region_device *rd)
Definition: region.h:148
void xlate_region_device_ro_init(struct xlate_region_device *xdev, size_t window_count, const struct xlate_window *window_arr, size_t parent_size)
Definition: region.c:200
static size_t region_offset(const struct region *r)
Definition: region.h:105
static bool init_done
Definition: sd_media.c:99
uintptr_t base
Definition: uart.c:17
static size_t bios_size
Definition: mmap_boot.c:43
static struct xlate_window real_dev_windows[TOTAL_DECODE_WINDOWS]
Definition: mmap_boot.c:26
static void initialize_window(enum window_type type, uintptr_t host_base, uintptr_t flash_base, size_t size)
Definition: mmap_boot.c:28
window_type
Definition: mmap_boot.c:16
@ FIXED_DECODE_WINDOW
Definition: mmap_boot.c:18
@ TOTAL_DECODE_WINDOWS
Definition: mmap_boot.c:21
@ EXT_BIOS_DECODE_WINDOW
Definition: mmap_boot.c:20
static struct xlate_region_device real_dev
Definition: mmap_boot.c:24
void fast_spi_get_ext_bios_window(uintptr_t *base, size_t *size)
Definition: mmap_boot.c:146
static struct mem_region_device shadow_devs[TOTAL_DECODE_WINDOWS]
Definition: mmap_boot.c:25
static void bios_mmap_init(void)
Definition: mmap_boot.c:82
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
struct region_device rdev
Definition: region.h:184
struct region_device rdev
Definition: region.h:255
#define count