mb/google/nissa: Create pujjogatwin variant
[coreboot2.git] / src / mainboard / emulation / qemu-i440fx / rom_media.c
blobf4fd3c37751e18c4e0c0994ce78cfce79c1567e5
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /* Inspired by OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c from edk2 */
5 #include <arch/mmio.h>
6 #include <boot_device.h>
7 #include <console/console.h>
8 #include <commonlib/helpers.h>
9 #include <commonlib/region.h>
10 #include <string.h>
12 #define WRITE_BYTE_CMD 0x10
13 #define BLOCK_ERASE_CMD 0x20
14 #define CLEAR_STATUS_CMD 0x50
15 #define READ_STATUS_CMD 0x70
16 #define BLOCK_ERASE_CONFIRM_CMD 0xD0
17 #define READ_ARRAY_CMD 0xFF
19 #define CLEARED_ARRAY_STATUS 0x00
21 #define QEMU_FLASH_BLOCK_SIZE 0x1000
23 #if CONFIG(ELOG)
24 #include <southbridge/intel/common/pmutil.h>
27 * ELOG and VBOOT options are automatically enabled when building with
28 * CHROMEOS=y. While the former allows for logging PCH state (not that there is
29 * much to log on QEMU), the latter currently forces 16 MiB ROM size, which in
30 * turn doesn't allow mounting as pflash in QEMU. Using pflash is required to
31 * have writable flash, which means that the following function will not be
32 * able to write to the flash based log until ROM size and layout is changed in
33 * Flashmap used when building for vboot.
35 void pch_log_state(void) {}
36 #endif
38 static ssize_t qemu_writeat(const struct region_device *rd, const void *b,
39 size_t offset, size_t size)
41 const struct mem_region_device *mdev;
42 size_t i;
43 volatile char *ptr;
44 const char *buf = b;
46 mdev = container_of(rd, __typeof__(*mdev), rdev);
47 ptr = &mdev->base[offset];
49 for (i = 0; i < size; i++) {
50 write8(ptr, WRITE_BYTE_CMD);
51 write8(ptr, buf[i]);
52 ptr++;
55 /* Restore flash to read mode. */
56 if (size > 0) {
57 write8(ptr - 1, READ_ARRAY_CMD);
60 return size;
63 static ssize_t qemu_eraseat(const struct region_device *rd, size_t offset,
64 size_t size)
66 const struct mem_region_device *mdev;
67 size_t i;
68 volatile char *ptr;
70 mdev = container_of(rd, __typeof__(*mdev), rdev);
71 ptr = &mdev->base[offset];
73 if (!IS_ALIGNED(offset, QEMU_FLASH_BLOCK_SIZE)) {
74 printk(BIOS_ERR, "%s: erased offset isn't multiple of block size\n",
75 __func__);
76 return -1;
79 if (!IS_ALIGNED(size, QEMU_FLASH_BLOCK_SIZE)) {
80 printk(BIOS_ERR, "%s: erased size isn't multiple of block size\n",
81 __func__);
82 return -1;
85 for (i = 0; i < size; i += QEMU_FLASH_BLOCK_SIZE) {
86 write8(ptr, BLOCK_ERASE_CMD);
87 write8(ptr, BLOCK_ERASE_CONFIRM_CMD);
88 ptr += QEMU_FLASH_BLOCK_SIZE;
91 /* Restore flash to read mode. */
92 if (size > 0) {
93 write8(ptr - QEMU_FLASH_BLOCK_SIZE, READ_ARRAY_CMD);
96 return size;
99 static struct region_device_ops flash_ops;
100 static const struct mem_region_device boot_dev =
101 MEM_REGION_DEV_INIT(0x100000000ULL - CONFIG_ROM_SIZE, CONFIG_ROM_SIZE, &flash_ops);
104 * Depending on how firmware image was passed to QEMU, it may behave as:
106 * - ROM - memory mapped reads, writes are ignored (FW image mounted with
107 * '-bios');
108 * - RAM - memory mapped reads and writes (FW image mounted with e.g.
109 * '-device loader');
110 * - flash - memory mapped reads, write and erase possible through commands.
111 * Contrary to physical flash devices erase is not required before writing,
112 * but it also doesn't hurt. Flash may be split into read-only and read-write
113 * parts, like OVMF_CODE.fd and OVMF_VARS.fd. Maximal combined size of system
114 * firmware is hardcoded (QEMU < 5.0.0) or set by default to 8 MiB. On QEMU
115 * version 5.0.0 or newer, it is configurable with `max-fw-size` machine
116 * configuration option, up to 16 MiB to not overlap with IOAPIC memory range
117 * (FW image(s) mounted with '-drive if=pflash').
119 * This function detects which of the above applies and fills region_device_ops
120 * accordingly.
122 void boot_device_init(void)
124 volatile char *ptr;
125 char original, readback;
126 static bool initialized = false;
128 if (initialized)
129 return;
132 * mmap, munmap and readat are always identical to mem_rdev_rw_ops, other
133 * functions may vary.
135 flash_ops = mem_rdev_rw_ops;
138 * Find first byte different than any of the commands, simplified.
140 * Detection code few lines below writes commands and tries to read back
141 * the response. To make that code simpler, make sure that original byte
142 * is different than any of the commands or expected responses. It is
143 * expected that such byte will always be found - it is virtually
144 * impossible to write valid x86 code with just bytes ending with 0, and
145 * there are also ASCII characters in metadata (CBFS, FMAP) that has bytes
146 * matching those assumptions.
148 ptr = (volatile char *)boot_dev.base;
149 original = read8(ptr);
150 while (original == (char)0xFF || (original & 0x0F) == 0)
151 original = read8(++ptr);
154 * Detect what type of flash we're dealing with. This also clears any stale
155 * status bits, so the next read of status register should return known
156 * value (if pflash is used).
158 write8(ptr, CLEAR_STATUS_CMD);
159 readback = read8(ptr);
160 if (readback == CLEAR_STATUS_CMD) {
161 printk(BIOS_DEBUG, "QEMU flash behaves as RAM\n");
162 /* Restore original content. */
163 write8(ptr, original);
164 } else {
165 /* Either ROM or QEMU flash implementation. */
166 write8(ptr, READ_STATUS_CMD);
167 readback = read8(ptr);
168 if (readback == original) {
169 printk(BIOS_DEBUG, "QEMU flash behaves as ROM\n");
170 /* ROM means no writing nor erasing. */
171 flash_ops.writeat = NULL;
172 flash_ops.eraseat = NULL;
173 } else if (readback == CLEARED_ARRAY_STATUS) {
174 /* Try writing original value to test whether flash is writable. */
175 write8(ptr, WRITE_BYTE_CMD);
176 write8(ptr, original);
177 write8(ptr, READ_STATUS_CMD);
178 readback = read8(ptr);
179 if (readback & 0x10 /* programming error */) {
180 printk(BIOS_DEBUG,
181 "QEMU flash behaves as write-protected flash\n");
182 flash_ops.writeat = NULL;
183 flash_ops.eraseat = NULL;
184 } else {
185 printk(BIOS_DEBUG, "QEMU flash behaves as writable flash\n");
186 flash_ops.writeat = qemu_writeat;
187 flash_ops.eraseat = qemu_eraseat;
189 /* Restore flash to read mode. */
190 write8(ptr, READ_ARRAY_CMD);
191 } else {
192 printk(BIOS_ERR, "Unexpected QEMU flash behavior, assuming ROM\n");
194 * This shouldn't happen and first byte of flash may already be
195 * corrupted by testing, but don't take any further risk.
197 flash_ops.writeat = NULL;
198 flash_ops.eraseat = NULL;
202 initialized = true;
205 /* boot_device_ro() is defined in arch/x86/mmap_boot.c */
206 const struct region_device *boot_device_rw(void)
208 return &boot_dev.rdev;