1*5f74217cSAbdelkader Boudih /*
2*5f74217cSAbdelkader Boudih * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com>
3*5f74217cSAbdelkader Boudih *
4*5f74217cSAbdelkader Boudih * SPDX-License-Identifier: BSD-2-Clause
5*5f74217cSAbdelkader Boudih */
6*5f74217cSAbdelkader Boudih
7*5f74217cSAbdelkader Boudih /*
8*5f74217cSAbdelkader Boudih * coreboot(4) driver for FreeBSD
9*5f74217cSAbdelkader Boudih *
10*5f74217cSAbdelkader Boudih * Structures and constants derived from the coreboot table specification.
11*5f74217cSAbdelkader Boudih */
12*5f74217cSAbdelkader Boudih
13*5f74217cSAbdelkader Boudih #ifndef _DEV_COREBOOT_COREBOOT_H_
14*5f74217cSAbdelkader Boudih #define _DEV_COREBOOT_COREBOOT_H_
15*5f74217cSAbdelkader Boudih
16*5f74217cSAbdelkader Boudih #include <sys/types.h>
17*5f74217cSAbdelkader Boudih #include <sys/conf.h>
18*5f74217cSAbdelkader Boudih #include <sys/sysctl.h>
19*5f74217cSAbdelkader Boudih #include <sys/bus.h>
20*5f74217cSAbdelkader Boudih
21*5f74217cSAbdelkader Boudih #include <dev/coreboot/corebootio.h>
22*5f74217cSAbdelkader Boudih
23*5f74217cSAbdelkader Boudih #define CB_HEADER_SIGNATURE "LBIO"
24*5f74217cSAbdelkader Boudih #define CB_HEADER_SIG_LEN 4
25*5f74217cSAbdelkader Boudih
26*5f74217cSAbdelkader Boudih /*
27*5f74217cSAbdelkader Boudih * Memory scan range for coreboot table discovery.
28*5f74217cSAbdelkader Boudih * Low memory (0x0–0x1000) contains a forward pointer to the real table.
29*5f74217cSAbdelkader Boudih */
30*5f74217cSAbdelkader Boudih #define CB_SCAN_LOW_START 0x00000000
31*5f74217cSAbdelkader Boudih #define CB_SCAN_LOW_END 0x00001000
32*5f74217cSAbdelkader Boudih #define CB_SCAN_LOW_STEP 16
33*5f74217cSAbdelkader Boudih
34*5f74217cSAbdelkader Boudih /*
35*5f74217cSAbdelkader Boudih * Defensive limits for parsing untrusted firmware-provided lengths.
36*5f74217cSAbdelkader Boudih */
37*5f74217cSAbdelkader Boudih #define CB_TABLE_ALIGN 4
38*5f74217cSAbdelkader Boudih #define CB_MAX_HEADER_BYTES 4096
39*5f74217cSAbdelkader Boudih #define CB_MAX_TABLE_BYTES (1024 * 1024)
40*5f74217cSAbdelkader Boudih #define CB_MAX_TABLE_MAP_BYTES (CB_MAX_HEADER_BYTES + CB_MAX_TABLE_BYTES)
41*5f74217cSAbdelkader Boudih #define CB_MAX_CONSOLE_BYTES (1024 * 1024)
42*5f74217cSAbdelkader Boudih
43*5f74217cSAbdelkader Boudih /*
44*5f74217cSAbdelkader Boudih * Coreboot table record tags - only tags we actually parse.
45*5f74217cSAbdelkader Boudih * Full enum preserved for forward compatibility (unknown tags are skipped).
46*5f74217cSAbdelkader Boudih */
47*5f74217cSAbdelkader Boudih enum cb_tag {
48*5f74217cSAbdelkader Boudih CB_TAG_UNUSED = 0x0000,
49*5f74217cSAbdelkader Boudih CB_TAG_MAINBOARD = 0x0003,
50*5f74217cSAbdelkader Boudih CB_TAG_VERSION = 0x0004,
51*5f74217cSAbdelkader Boudih CB_TAG_EXTRA_VERSION = 0x0005,
52*5f74217cSAbdelkader Boudih CB_TAG_BUILD = 0x0006,
53*5f74217cSAbdelkader Boudih CB_TAG_COMPILE_TIME = 0x0007,
54*5f74217cSAbdelkader Boudih CB_TAG_COMPILER = 0x000b,
55*5f74217cSAbdelkader Boudih CB_TAG_SERIAL = 0x000f,
56*5f74217cSAbdelkader Boudih CB_TAG_CONSOLE = 0x0010,
57*5f74217cSAbdelkader Boudih CB_TAG_FORWARD = 0x0011,
58*5f74217cSAbdelkader Boudih CB_TAG_FRAMEBUFFER = 0x0012,
59*5f74217cSAbdelkader Boudih CB_TAG_GPIO = 0x0013,
60*5f74217cSAbdelkader Boudih CB_TAG_TIMESTAMPS = 0x0016,
61*5f74217cSAbdelkader Boudih CB_TAG_CBMEM_CONSOLE = 0x0017,
62*5f74217cSAbdelkader Boudih CB_TAG_ACPI_GNVS = 0x0024,
63*5f74217cSAbdelkader Boudih CB_TAG_VERSION_TIMESTAMP = 0x0026,
64*5f74217cSAbdelkader Boudih CB_TAG_WIFI_CALIBRATION = 0x0027,
65*5f74217cSAbdelkader Boudih CB_TAG_SPI_FLASH = 0x0029,
66*5f74217cSAbdelkader Boudih CB_TAG_SERIALNO = 0x002a,
67*5f74217cSAbdelkader Boudih CB_TAG_VPD = 0x002c,
68*5f74217cSAbdelkader Boudih CB_TAG_BOOT_MEDIA_PARAMS = 0x0030,
69*5f74217cSAbdelkader Boudih CB_TAG_CBMEM_ENTRY = 0x0031,
70*5f74217cSAbdelkader Boudih CB_TAG_TSC_INFO = 0x0032,
71*5f74217cSAbdelkader Boudih CB_TAG_MAC_ADDRS = 0x0033,
72*5f74217cSAbdelkader Boudih CB_TAG_VBOOT_WORKBUF = 0x0034,
73*5f74217cSAbdelkader Boudih CB_TAG_MMC_INFO = 0x0035,
74*5f74217cSAbdelkader Boudih CB_TAG_TPM_CB_LOG = 0x0036,
75*5f74217cSAbdelkader Boudih CB_TAG_FMAP = 0x0037,
76*5f74217cSAbdelkader Boudih CB_TAG_PLATFORM_BLOB_VERSION = 0x0038,
77*5f74217cSAbdelkader Boudih CB_TAG_SMMSTOREV2 = 0x0039,
78*5f74217cSAbdelkader Boudih CB_TAG_TPM_PPI_HANDOFF = 0x003a,
79*5f74217cSAbdelkader Boudih CB_TAG_BOARD_CONFIG = 0x0040,
80*5f74217cSAbdelkader Boudih CB_TAG_ACPI_CNVS = 0x0041,
81*5f74217cSAbdelkader Boudih CB_TAG_TYPE_C_INFO = 0x0042,
82*5f74217cSAbdelkader Boudih CB_TAG_ACPI_RSDP = 0x0043,
83*5f74217cSAbdelkader Boudih CB_TAG_PCIE = 0x0044,
84*5f74217cSAbdelkader Boudih CB_TAG_ROOT_BRIDGE_INFO = 0x0048,
85*5f74217cSAbdelkader Boudih };
86*5f74217cSAbdelkader Boudih
87*5f74217cSAbdelkader Boudih /*
88*5f74217cSAbdelkader Boudih * Coreboot table header - located at a physical address found by scanning
89*5f74217cSAbdelkader Boudih * low memory for the "LBIO" signature.
90*5f74217cSAbdelkader Boudih */
91*5f74217cSAbdelkader Boudih struct cb_header {
92*5f74217cSAbdelkader Boudih uint8_t signature[CB_HEADER_SIG_LEN];
93*5f74217cSAbdelkader Boudih uint32_t header_bytes;
94*5f74217cSAbdelkader Boudih uint32_t header_checksum;
95*5f74217cSAbdelkader Boudih uint32_t table_bytes;
96*5f74217cSAbdelkader Boudih uint32_t table_checksum;
97*5f74217cSAbdelkader Boudih uint32_t table_entries;
98*5f74217cSAbdelkader Boudih } __packed;
99*5f74217cSAbdelkader Boudih
100*5f74217cSAbdelkader Boudih /*
101*5f74217cSAbdelkader Boudih * Generic record header - every table entry starts with this.
102*5f74217cSAbdelkader Boudih */
103*5f74217cSAbdelkader Boudih struct cb_record {
104*5f74217cSAbdelkader Boudih uint32_t tag;
105*5f74217cSAbdelkader Boudih uint32_t size;
106*5f74217cSAbdelkader Boudih } __packed;
107*5f74217cSAbdelkader Boudih
108*5f74217cSAbdelkader Boudih /*
109*5f74217cSAbdelkader Boudih * CB_TAG_FORWARD - pointer to the real table in high memory.
110*5f74217cSAbdelkader Boudih */
111*5f74217cSAbdelkader Boudih struct cb_forward {
112*5f74217cSAbdelkader Boudih uint32_t tag;
113*5f74217cSAbdelkader Boudih uint32_t size;
114*5f74217cSAbdelkader Boudih uint64_t forward;
115*5f74217cSAbdelkader Boudih } __packed;
116*5f74217cSAbdelkader Boudih
117*5f74217cSAbdelkader Boudih /*
118*5f74217cSAbdelkader Boudih * CB_TAG_MAINBOARD - board vendor and part number.
119*5f74217cSAbdelkader Boudih * Strings are packed after the struct, indexed by vendor_idx and part_idx.
120*5f74217cSAbdelkader Boudih */
121*5f74217cSAbdelkader Boudih struct cb_mainboard {
122*5f74217cSAbdelkader Boudih uint32_t tag;
123*5f74217cSAbdelkader Boudih uint32_t size;
124*5f74217cSAbdelkader Boudih uint8_t vendor_idx;
125*5f74217cSAbdelkader Boudih uint8_t part_idx;
126*5f74217cSAbdelkader Boudih uint8_t strings[];
127*5f74217cSAbdelkader Boudih } __packed;
128*5f74217cSAbdelkader Boudih
129*5f74217cSAbdelkader Boudih /*
130*5f74217cSAbdelkader Boudih * Variable-length string record - used by VERSION, BUILD, COMPILE_*, etc.
131*5f74217cSAbdelkader Boudih */
132*5f74217cSAbdelkader Boudih struct cb_string {
133*5f74217cSAbdelkader Boudih uint32_t tag;
134*5f74217cSAbdelkader Boudih uint32_t size;
135*5f74217cSAbdelkader Boudih uint8_t string[];
136*5f74217cSAbdelkader Boudih } __packed;
137*5f74217cSAbdelkader Boudih
138*5f74217cSAbdelkader Boudih /*
139*5f74217cSAbdelkader Boudih * CB_TAG_SERIAL - serial port configuration.
140*5f74217cSAbdelkader Boudih */
141*5f74217cSAbdelkader Boudih struct cb_serial {
142*5f74217cSAbdelkader Boudih uint32_t tag;
143*5f74217cSAbdelkader Boudih uint32_t size;
144*5f74217cSAbdelkader Boudih uint32_t type;
145*5f74217cSAbdelkader Boudih uint32_t baseaddr;
146*5f74217cSAbdelkader Boudih uint32_t baud;
147*5f74217cSAbdelkader Boudih uint32_t regwidth;
148*5f74217cSAbdelkader Boudih uint32_t input_hertz;
149*5f74217cSAbdelkader Boudih } __packed;
150*5f74217cSAbdelkader Boudih
151*5f74217cSAbdelkader Boudih /*
152*5f74217cSAbdelkader Boudih * CB_TAG_CBMEM_CONSOLE - pointer to firmware console ring buffer.
153*5f74217cSAbdelkader Boudih */
154*5f74217cSAbdelkader Boudih struct cb_cbmem_ref {
155*5f74217cSAbdelkader Boudih uint32_t tag;
156*5f74217cSAbdelkader Boudih uint32_t size;
157*5f74217cSAbdelkader Boudih uint64_t cbmem_addr;
158*5f74217cSAbdelkader Boudih } __packed;
159*5f74217cSAbdelkader Boudih
160*5f74217cSAbdelkader Boudih /*
161*5f74217cSAbdelkader Boudih * CB_TAG_CBMEM_ENTRY - one per CBMEM region.
162*5f74217cSAbdelkader Boudih */
163*5f74217cSAbdelkader Boudih struct cb_cbmem_entry {
164*5f74217cSAbdelkader Boudih uint32_t tag;
165*5f74217cSAbdelkader Boudih uint32_t size;
166*5f74217cSAbdelkader Boudih uint64_t address;
167*5f74217cSAbdelkader Boudih uint32_t entry_size;
168*5f74217cSAbdelkader Boudih uint32_t id;
169*5f74217cSAbdelkader Boudih } __packed;
170*5f74217cSAbdelkader Boudih
171*5f74217cSAbdelkader Boudih /*
172*5f74217cSAbdelkader Boudih * CB_TAG_TSC_INFO - TSC frequency.
173*5f74217cSAbdelkader Boudih */
174*5f74217cSAbdelkader Boudih struct cb_tsc_info {
175*5f74217cSAbdelkader Boudih uint32_t tag;
176*5f74217cSAbdelkader Boudih uint32_t size;
177*5f74217cSAbdelkader Boudih uint32_t freq_khz;
178*5f74217cSAbdelkader Boudih } __packed;
179*5f74217cSAbdelkader Boudih
180*5f74217cSAbdelkader Boudih /*
181*5f74217cSAbdelkader Boudih * CB_TAG_VERSION_TIMESTAMP - build version timestamp.
182*5f74217cSAbdelkader Boudih * timestamp is Unix time in seconds (seconds since 1970-01-01 UTC).
183*5f74217cSAbdelkader Boudih */
184*5f74217cSAbdelkader Boudih struct cb_version_timestamp {
185*5f74217cSAbdelkader Boudih uint32_t tag;
186*5f74217cSAbdelkader Boudih uint32_t size;
187*5f74217cSAbdelkader Boudih uint32_t timestamp;
188*5f74217cSAbdelkader Boudih } __packed;
189*5f74217cSAbdelkader Boudih
190*5f74217cSAbdelkader Boudih /*
191*5f74217cSAbdelkader Boudih * CB_TAG_BOARD_CONFIG - board identification and firmware config.
192*5f74217cSAbdelkader Boudih */
193*5f74217cSAbdelkader Boudih struct cb_board_config {
194*5f74217cSAbdelkader Boudih uint32_t tag;
195*5f74217cSAbdelkader Boudih uint32_t size;
196*5f74217cSAbdelkader Boudih uint64_t fw_config;
197*5f74217cSAbdelkader Boudih uint32_t board_id;
198*5f74217cSAbdelkader Boudih uint32_t ram_code;
199*5f74217cSAbdelkader Boudih uint32_t sku_id;
200*5f74217cSAbdelkader Boudih } __packed;
201*5f74217cSAbdelkader Boudih
202*5f74217cSAbdelkader Boudih /*
203*5f74217cSAbdelkader Boudih * CB_TAG_BOOT_MEDIA_PARAMS - offsets and sizes on boot media.
204*5f74217cSAbdelkader Boudih */
205*5f74217cSAbdelkader Boudih struct cb_boot_media_params {
206*5f74217cSAbdelkader Boudih uint32_t tag;
207*5f74217cSAbdelkader Boudih uint32_t size;
208*5f74217cSAbdelkader Boudih uint64_t fmap_offset;
209*5f74217cSAbdelkader Boudih uint64_t cbfs_offset;
210*5f74217cSAbdelkader Boudih uint64_t cbfs_size;
211*5f74217cSAbdelkader Boudih uint64_t boot_media_size;
212*5f74217cSAbdelkader Boudih } __packed;
213*5f74217cSAbdelkader Boudih
214*5f74217cSAbdelkader Boudih /*
215*5f74217cSAbdelkader Boudih * CB_TAG_MMC_INFO - early eMMC/MMC status.
216*5f74217cSAbdelkader Boudih */
217*5f74217cSAbdelkader Boudih struct cb_mmc_info {
218*5f74217cSAbdelkader Boudih uint32_t tag;
219*5f74217cSAbdelkader Boudih uint32_t size;
220*5f74217cSAbdelkader Boudih int32_t early_cmd1_status;
221*5f74217cSAbdelkader Boudih } __packed;
222*5f74217cSAbdelkader Boudih
223*5f74217cSAbdelkader Boudih /*
224*5f74217cSAbdelkader Boudih * CB_TAG_PCIE - PCIe controller base address.
225*5f74217cSAbdelkader Boudih */
226*5f74217cSAbdelkader Boudih struct cb_pcie {
227*5f74217cSAbdelkader Boudih uint32_t tag;
228*5f74217cSAbdelkader Boudih uint32_t size;
229*5f74217cSAbdelkader Boudih uint64_t ctrl_base;
230*5f74217cSAbdelkader Boudih } __packed;
231*5f74217cSAbdelkader Boudih
232*5f74217cSAbdelkader Boudih /*
233*5f74217cSAbdelkader Boudih * CB_TAG_MAC_ADDRS - factory-provisioned MAC addresses.
234*5f74217cSAbdelkader Boudih */
235*5f74217cSAbdelkader Boudih struct cb_mac_address {
236*5f74217cSAbdelkader Boudih uint8_t mac_addr[6];
237*5f74217cSAbdelkader Boudih uint8_t pad[2];
238*5f74217cSAbdelkader Boudih } __packed;
239*5f74217cSAbdelkader Boudih
240*5f74217cSAbdelkader Boudih struct cb_macs {
241*5f74217cSAbdelkader Boudih uint32_t tag;
242*5f74217cSAbdelkader Boudih uint32_t size;
243*5f74217cSAbdelkader Boudih uint32_t count;
244*5f74217cSAbdelkader Boudih struct cb_mac_address entries[];
245*5f74217cSAbdelkader Boudih } __packed;
246*5f74217cSAbdelkader Boudih
247*5f74217cSAbdelkader Boudih /*
248*5f74217cSAbdelkader Boudih * CB_TAG_SPI_FLASH - SPI flash chip parameters.
249*5f74217cSAbdelkader Boudih */
250*5f74217cSAbdelkader Boudih struct cb_flash_mmap_window {
251*5f74217cSAbdelkader Boudih uint32_t flash_base;
252*5f74217cSAbdelkader Boudih uint32_t host_base;
253*5f74217cSAbdelkader Boudih uint32_t size;
254*5f74217cSAbdelkader Boudih } __packed;
255*5f74217cSAbdelkader Boudih
256*5f74217cSAbdelkader Boudih struct cb_spi_flash {
257*5f74217cSAbdelkader Boudih uint32_t tag;
258*5f74217cSAbdelkader Boudih uint32_t size;
259*5f74217cSAbdelkader Boudih uint32_t flash_size;
260*5f74217cSAbdelkader Boudih uint32_t sector_size;
261*5f74217cSAbdelkader Boudih uint8_t erase_cmd;
262*5f74217cSAbdelkader Boudih uint8_t flags;
263*5f74217cSAbdelkader Boudih uint16_t reserved;
264*5f74217cSAbdelkader Boudih uint32_t mmap_count;
265*5f74217cSAbdelkader Boudih struct cb_flash_mmap_window mmap_table[];
266*5f74217cSAbdelkader Boudih } __packed;
267*5f74217cSAbdelkader Boudih
268*5f74217cSAbdelkader Boudih /*
269*5f74217cSAbdelkader Boudih * CB_TAG_CONSOLE - firmware console type.
270*5f74217cSAbdelkader Boudih */
271*5f74217cSAbdelkader Boudih struct cb_console {
272*5f74217cSAbdelkader Boudih uint32_t tag;
273*5f74217cSAbdelkader Boudih uint32_t size;
274*5f74217cSAbdelkader Boudih uint16_t type;
275*5f74217cSAbdelkader Boudih uint8_t pad[2];
276*5f74217cSAbdelkader Boudih } __packed;
277*5f74217cSAbdelkader Boudih
278*5f74217cSAbdelkader Boudih #define CB_CONSOLE_SERIAL8250 0
279*5f74217cSAbdelkader Boudih #define CB_CONSOLE_VGA 1 /* obsolete */
280*5f74217cSAbdelkader Boudih #define CB_CONSOLE_EHCI 5
281*5f74217cSAbdelkader Boudih #define CB_CONSOLE_SERIAL8250MEM 6
282*5f74217cSAbdelkader Boudih
283*5f74217cSAbdelkader Boudih /*
284*5f74217cSAbdelkader Boudih * CB_TAG_FRAMEBUFFER - linear framebuffer info.
285*5f74217cSAbdelkader Boudih * The orientation, flags, and pad fields were added later.
286*5f74217cSAbdelkader Boudih * Minimum record size is up to reserved_mask_size (29 bytes).
287*5f74217cSAbdelkader Boudih */
288*5f74217cSAbdelkader Boudih #define CB_FRAMEBUFFER_MIN_SIZE 29
289*5f74217cSAbdelkader Boudih struct cb_framebuffer {
290*5f74217cSAbdelkader Boudih uint32_t tag;
291*5f74217cSAbdelkader Boudih uint32_t size;
292*5f74217cSAbdelkader Boudih uint64_t physical_address;
293*5f74217cSAbdelkader Boudih uint32_t x_resolution;
294*5f74217cSAbdelkader Boudih uint32_t y_resolution;
295*5f74217cSAbdelkader Boudih uint32_t bytes_per_line;
296*5f74217cSAbdelkader Boudih uint8_t bits_per_pixel;
297*5f74217cSAbdelkader Boudih uint8_t red_mask_pos;
298*5f74217cSAbdelkader Boudih uint8_t red_mask_size;
299*5f74217cSAbdelkader Boudih uint8_t green_mask_pos;
300*5f74217cSAbdelkader Boudih uint8_t green_mask_size;
301*5f74217cSAbdelkader Boudih uint8_t blue_mask_pos;
302*5f74217cSAbdelkader Boudih uint8_t blue_mask_size;
303*5f74217cSAbdelkader Boudih uint8_t reserved_mask_pos;
304*5f74217cSAbdelkader Boudih uint8_t reserved_mask_size;
305*5f74217cSAbdelkader Boudih uint8_t orientation;
306*5f74217cSAbdelkader Boudih uint8_t flags;
307*5f74217cSAbdelkader Boudih uint8_t pad;
308*5f74217cSAbdelkader Boudih } __packed;
309*5f74217cSAbdelkader Boudih
310*5f74217cSAbdelkader Boudih /*
311*5f74217cSAbdelkader Boudih * CB_TAG_GPIO - GPIO pin states.
312*5f74217cSAbdelkader Boudih */
313*5f74217cSAbdelkader Boudih struct cb_gpio {
314*5f74217cSAbdelkader Boudih uint32_t port;
315*5f74217cSAbdelkader Boudih uint32_t polarity;
316*5f74217cSAbdelkader Boudih uint32_t value;
317*5f74217cSAbdelkader Boudih uint8_t name[16];
318*5f74217cSAbdelkader Boudih } __packed;
319*5f74217cSAbdelkader Boudih
320*5f74217cSAbdelkader Boudih struct cb_gpios {
321*5f74217cSAbdelkader Boudih uint32_t tag;
322*5f74217cSAbdelkader Boudih uint32_t size;
323*5f74217cSAbdelkader Boudih uint32_t count;
324*5f74217cSAbdelkader Boudih struct cb_gpio entries[];
325*5f74217cSAbdelkader Boudih } __packed;
326*5f74217cSAbdelkader Boudih
327*5f74217cSAbdelkader Boudih /*
328*5f74217cSAbdelkader Boudih * CB_TAG_TPM_PPI_HANDOFF - TPM Physical Presence Interface handoff.
329*5f74217cSAbdelkader Boudih */
330*5f74217cSAbdelkader Boudih struct cb_tpm_ppi {
331*5f74217cSAbdelkader Boudih uint32_t tag;
332*5f74217cSAbdelkader Boudih uint32_t size;
333*5f74217cSAbdelkader Boudih uint32_t ppi_address;
334*5f74217cSAbdelkader Boudih uint8_t tpm_version; /* 1=TPM1.2, 2=TPM2.0 */
335*5f74217cSAbdelkader Boudih uint8_t ppi_version; /* BCD encoded */
336*5f74217cSAbdelkader Boudih uint8_t pad[2];
337*5f74217cSAbdelkader Boudih } __packed;
338*5f74217cSAbdelkader Boudih
339*5f74217cSAbdelkader Boudih /*
340*5f74217cSAbdelkader Boudih * CB_TAG_SMMSTOREV2 - SMM-based variable store configuration.
341*5f74217cSAbdelkader Boudih *
342*5f74217cSAbdelkader Boudih * The mmap_addr field was added after the initial implementation.
343*5f74217cSAbdelkader Boudih * Older coreboot emits a shorter record (32 bytes) without it.
344*5f74217cSAbdelkader Boudih * Consumers must check rec->size to detect whether mmap_addr is present.
345*5f74217cSAbdelkader Boudih */
346*5f74217cSAbdelkader Boudih #define CB_SMMSTOREV2_BASE_SIZE 32 /* size without mmap_addr */
347*5f74217cSAbdelkader Boudih struct cb_smmstorev2 {
348*5f74217cSAbdelkader Boudih uint32_t tag;
349*5f74217cSAbdelkader Boudih uint32_t size;
350*5f74217cSAbdelkader Boudih uint32_t num_blocks;
351*5f74217cSAbdelkader Boudih uint32_t block_size;
352*5f74217cSAbdelkader Boudih uint32_t mmap_addr_lo; /* deprecated 32-bit address */
353*5f74217cSAbdelkader Boudih uint32_t com_buffer;
354*5f74217cSAbdelkader Boudih uint32_t com_buffer_size;
355*5f74217cSAbdelkader Boudih uint8_t apm_cmd;
356*5f74217cSAbdelkader Boudih uint8_t unused[3];
357*5f74217cSAbdelkader Boudih /* Fields below only present if size > CB_SMMSTOREV2_BASE_SIZE */
358*5f74217cSAbdelkader Boudih uint64_t mmap_addr; /* 64-bit address (preferred) */
359*5f74217cSAbdelkader Boudih } __packed;
360*5f74217cSAbdelkader Boudih
361*5f74217cSAbdelkader Boudih /*
362*5f74217cSAbdelkader Boudih * CB_TAG_ACPI_RSDP - ACPI Root System Description Pointer address.
363*5f74217cSAbdelkader Boudih */
364*5f74217cSAbdelkader Boudih struct cb_acpi_rsdp {
365*5f74217cSAbdelkader Boudih uint32_t tag;
366*5f74217cSAbdelkader Boudih uint32_t size;
367*5f74217cSAbdelkader Boudih uint64_t rsdp_pointer;
368*5f74217cSAbdelkader Boudih } __packed;
369*5f74217cSAbdelkader Boudih
370*5f74217cSAbdelkader Boudih /*
371*5f74217cSAbdelkader Boudih * CBMEM console ring buffer (in-memory structure at cbmem_addr).
372*5f74217cSAbdelkader Boudih * Bit 31 of cursor indicates overflow (ring has wrapped).
373*5f74217cSAbdelkader Boudih */
374*5f74217cSAbdelkader Boudih struct cbmem_console {
375*5f74217cSAbdelkader Boudih uint32_t size;
376*5f74217cSAbdelkader Boudih uint32_t cursor;
377*5f74217cSAbdelkader Boudih uint8_t body[];
378*5f74217cSAbdelkader Boudih } __packed;
379*5f74217cSAbdelkader Boudih
380*5f74217cSAbdelkader Boudih #define CBMEM_CONSOLE_CURSOR_MASK ((1 << 28) - 1)
381*5f74217cSAbdelkader Boudih #define CBMEM_CONSOLE_OVERFLOW (1 << 31)
382*5f74217cSAbdelkader Boudih
383*5f74217cSAbdelkader Boudih #define CB_MAX_MAC_ADDRS 8
384*5f74217cSAbdelkader Boudih #define CB_MAX_GPIOS 32
385*5f74217cSAbdelkader Boudih
386*5f74217cSAbdelkader Boudih /*
387*5f74217cSAbdelkader Boudih * Driver softc
388*5f74217cSAbdelkader Boudih */
389*5f74217cSAbdelkader Boudih struct coreboot_softc {
390*5f74217cSAbdelkader Boudih device_t dev;
391*5f74217cSAbdelkader Boudih
392*5f74217cSAbdelkader Boudih vm_paddr_t table_paddr;
393*5f74217cSAbdelkader Boudih vm_size_t table_size;
394*5f74217cSAbdelkader Boudih void *table_vaddr;
395*5f74217cSAbdelkader Boudih
396*5f74217cSAbdelkader Boudih char version[64];
397*5f74217cSAbdelkader Boudih char build[64];
398*5f74217cSAbdelkader Boudih char compile_time[64];
399*5f74217cSAbdelkader Boudih char compiler[128];
400*5f74217cSAbdelkader Boudih char extra_version[64];
401*5f74217cSAbdelkader Boudih char platform_blob_version[64];
402*5f74217cSAbdelkader Boudih char serialno[64];
403*5f74217cSAbdelkader Boudih uint32_t version_timestamp;
404*5f74217cSAbdelkader Boudih int has_version_timestamp;
405*5f74217cSAbdelkader Boudih
406*5f74217cSAbdelkader Boudih char mb_vendor[64];
407*5f74217cSAbdelkader Boudih char mb_part[64];
408*5f74217cSAbdelkader Boudih
409*5f74217cSAbdelkader Boudih uint32_t serial_baseaddr;
410*5f74217cSAbdelkader Boudih uint32_t serial_baud;
411*5f74217cSAbdelkader Boudih uint32_t serial_regwidth;
412*5f74217cSAbdelkader Boudih int has_serial;
413*5f74217cSAbdelkader Boudih
414*5f74217cSAbdelkader Boudih uint32_t tsc_freq_khz;
415*5f74217cSAbdelkader Boudih int has_tsc_info;
416*5f74217cSAbdelkader Boudih
417*5f74217cSAbdelkader Boudih uint64_t pcie_ctrl_base;
418*5f74217cSAbdelkader Boudih int has_pcie;
419*5f74217cSAbdelkader Boudih
420*5f74217cSAbdelkader Boudih uint64_t fmap_offset;
421*5f74217cSAbdelkader Boudih uint64_t cbfs_offset;
422*5f74217cSAbdelkader Boudih uint64_t cbfs_size;
423*5f74217cSAbdelkader Boudih uint64_t boot_media_size;
424*5f74217cSAbdelkader Boudih int has_boot_media;
425*5f74217cSAbdelkader Boudih
426*5f74217cSAbdelkader Boudih int32_t mmc_early_cmd1_status;
427*5f74217cSAbdelkader Boudih int has_mmc_info;
428*5f74217cSAbdelkader Boudih
429*5f74217cSAbdelkader Boudih vm_paddr_t console_paddr;
430*5f74217cSAbdelkader Boudih vm_size_t console_size;
431*5f74217cSAbdelkader Boudih uint32_t console_data_size;
432*5f74217cSAbdelkader Boudih struct cbmem_console *console_vaddr;
433*5f74217cSAbdelkader Boudih int has_console;
434*5f74217cSAbdelkader Boudih struct cdev *console_cdev;
435*5f74217cSAbdelkader Boudih
436*5f74217cSAbdelkader Boudih uint32_t cbmem_count;
437*5f74217cSAbdelkader Boudih struct cbmem_entry_info cbmem_entries[CB_MAX_CBMEM_ENTRIES];
438*5f74217cSAbdelkader Boudih struct cdev *cbmem_cdev;
439*5f74217cSAbdelkader Boudih
440*5f74217cSAbdelkader Boudih uint64_t fw_config;
441*5f74217cSAbdelkader Boudih uint32_t board_id;
442*5f74217cSAbdelkader Boudih uint32_t ram_code;
443*5f74217cSAbdelkader Boudih uint32_t sku_id;
444*5f74217cSAbdelkader Boudih int has_board_config;
445*5f74217cSAbdelkader Boudih
446*5f74217cSAbdelkader Boudih uint32_t mac_count;
447*5f74217cSAbdelkader Boudih struct cb_mac_address macs[CB_MAX_MAC_ADDRS];
448*5f74217cSAbdelkader Boudih char mac_strs[CB_MAX_MAC_ADDRS][18];
449*5f74217cSAbdelkader Boudih
450*5f74217cSAbdelkader Boudih uint64_t acpi_rsdp;
451*5f74217cSAbdelkader Boudih int has_acpi_rsdp;
452*5f74217cSAbdelkader Boudih
453*5f74217cSAbdelkader Boudih uint32_t spi_flash_size;
454*5f74217cSAbdelkader Boudih uint32_t spi_sector_size;
455*5f74217cSAbdelkader Boudih uint8_t spi_erase_cmd;
456*5f74217cSAbdelkader Boudih uint8_t spi_flags;
457*5f74217cSAbdelkader Boudih int has_spi_flash;
458*5f74217cSAbdelkader Boudih
459*5f74217cSAbdelkader Boudih uint16_t console_type;
460*5f74217cSAbdelkader Boudih int has_console_type;
461*5f74217cSAbdelkader Boudih
462*5f74217cSAbdelkader Boudih uint64_t fb_addr;
463*5f74217cSAbdelkader Boudih uint32_t fb_x_res;
464*5f74217cSAbdelkader Boudih uint32_t fb_y_res;
465*5f74217cSAbdelkader Boudih uint32_t fb_stride;
466*5f74217cSAbdelkader Boudih uint8_t fb_bpp;
467*5f74217cSAbdelkader Boudih int has_framebuffer;
468*5f74217cSAbdelkader Boudih
469*5f74217cSAbdelkader Boudih uint32_t gpio_count;
470*5f74217cSAbdelkader Boudih struct cb_gpio gpios[CB_MAX_GPIOS];
471*5f74217cSAbdelkader Boudih
472*5f74217cSAbdelkader Boudih uint32_t tpm_ppi_addr;
473*5f74217cSAbdelkader Boudih uint8_t tpm_version;
474*5f74217cSAbdelkader Boudih int has_tpm;
475*5f74217cSAbdelkader Boudih
476*5f74217cSAbdelkader Boudih vm_paddr_t tpm_log_paddr;
477*5f74217cSAbdelkader Boudih int has_tpm_log;
478*5f74217cSAbdelkader Boudih
479*5f74217cSAbdelkader Boudih vm_paddr_t acpi_gnvs_paddr;
480*5f74217cSAbdelkader Boudih int has_acpi_gnvs;
481*5f74217cSAbdelkader Boudih vm_paddr_t acpi_cnvs_paddr;
482*5f74217cSAbdelkader Boudih int has_acpi_cnvs;
483*5f74217cSAbdelkader Boudih vm_paddr_t vpd_paddr;
484*5f74217cSAbdelkader Boudih int has_vpd;
485*5f74217cSAbdelkader Boudih vm_paddr_t wifi_cal_paddr;
486*5f74217cSAbdelkader Boudih int has_wifi_cal;
487*5f74217cSAbdelkader Boudih vm_paddr_t fmap_paddr;
488*5f74217cSAbdelkader Boudih int has_fmap;
489*5f74217cSAbdelkader Boudih vm_paddr_t vboot_workbuf_paddr;
490*5f74217cSAbdelkader Boudih int has_vboot_workbuf;
491*5f74217cSAbdelkader Boudih vm_paddr_t type_c_info_paddr;
492*5f74217cSAbdelkader Boudih int has_type_c_info;
493*5f74217cSAbdelkader Boudih vm_paddr_t root_bridge_info_paddr;
494*5f74217cSAbdelkader Boudih int has_root_bridge_info;
495*5f74217cSAbdelkader Boudih
496*5f74217cSAbdelkader Boudih uint32_t smmstore_num_blocks;
497*5f74217cSAbdelkader Boudih uint32_t smmstore_block_size;
498*5f74217cSAbdelkader Boudih uint64_t smmstore_mmap_addr;
499*5f74217cSAbdelkader Boudih uint32_t smmstore_com_buffer;
500*5f74217cSAbdelkader Boudih uint8_t smmstore_apm_cmd;
501*5f74217cSAbdelkader Boudih int has_smmstore;
502*5f74217cSAbdelkader Boudih
503*5f74217cSAbdelkader Boudih vm_paddr_t timestamps_paddr;
504*5f74217cSAbdelkader Boudih int has_timestamps;
505*5f74217cSAbdelkader Boudih
506*5f74217cSAbdelkader Boudih struct sysctl_ctx_list sysctl_ctx;
507*5f74217cSAbdelkader Boudih struct sysctl_oid *sysctl_tree;
508*5f74217cSAbdelkader Boudih };
509*5f74217cSAbdelkader Boudih
510*5f74217cSAbdelkader Boudih /*
511*5f74217cSAbdelkader Boudih * Generic ID-to-name linear search.
512*5f74217cSAbdelkader Boudih * The table must be terminated by an entry with name == NULL.
513*5f74217cSAbdelkader Boudih * Returns fallback if no match is found.
514*5f74217cSAbdelkader Boudih */
515*5f74217cSAbdelkader Boudih struct cb_id_name {
516*5f74217cSAbdelkader Boudih uint32_t id;
517*5f74217cSAbdelkader Boudih const char *name;
518*5f74217cSAbdelkader Boudih };
519*5f74217cSAbdelkader Boudih
520*5f74217cSAbdelkader Boudih static __inline const char *
cb_id_lookup(const struct cb_id_name * tbl,uint32_t id,const char * fallback)521*5f74217cSAbdelkader Boudih cb_id_lookup(const struct cb_id_name *tbl, uint32_t id, const char *fallback)
522*5f74217cSAbdelkader Boudih {
523*5f74217cSAbdelkader Boudih int i;
524*5f74217cSAbdelkader Boudih
525*5f74217cSAbdelkader Boudih for (i = 0; tbl[i].name != NULL; i++) {
526*5f74217cSAbdelkader Boudih if (tbl[i].id == id)
527*5f74217cSAbdelkader Boudih return (tbl[i].name);
528*5f74217cSAbdelkader Boudih }
529*5f74217cSAbdelkader Boudih return (fallback);
530*5f74217cSAbdelkader Boudih }
531*5f74217cSAbdelkader Boudih
532*5f74217cSAbdelkader Boudih /*
533*5f74217cSAbdelkader Boudih * CBMEM ID to human-readable name lookup.
534*5f74217cSAbdelkader Boudih */
535*5f74217cSAbdelkader Boudih static __inline const char *
cbmem_id_to_name(uint32_t id)536*5f74217cSAbdelkader Boudih cbmem_id_to_name(uint32_t id)
537*5f74217cSAbdelkader Boudih {
538*5f74217cSAbdelkader Boudih static const struct cb_id_name names[] = {
539*5f74217cSAbdelkader Boudih { CBMEM_ID_ACPI, "ACPI" },
540*5f74217cSAbdelkader Boudih { CBMEM_ID_ACPI_GNVS, "ACPI GNVS" },
541*5f74217cSAbdelkader Boudih { CBMEM_ID_AFTER_CAR, "AFTER CAR" },
542*5f74217cSAbdelkader Boudih { CBMEM_ID_CBTABLE, "COREBOOT" },
543*5f74217cSAbdelkader Boudih { CBMEM_ID_CBTABLE_FWD, "COREBOOT FWD" },
544*5f74217cSAbdelkader Boudih { CBMEM_ID_CBFS_RO_MCACHE, "RO MCACHE" },
545*5f74217cSAbdelkader Boudih { CBMEM_ID_CBFS_RW_MCACHE, "RW MCACHE" },
546*5f74217cSAbdelkader Boudih { CBMEM_ID_CONSOLE, "CONSOLE" },
547*5f74217cSAbdelkader Boudih { CBMEM_ID_ELOG, "ELOG" },
548*5f74217cSAbdelkader Boudih { CBMEM_ID_FMAP, "FMAP" },
549*5f74217cSAbdelkader Boudih { CBMEM_ID_FREESPACE, "FREE SPACE" },
550*5f74217cSAbdelkader Boudih { CBMEM_ID_FSP_RESERVED_MEMORY, "FSP MEMORY" },
551*5f74217cSAbdelkader Boudih { CBMEM_ID_FSP_RUNTIME, "FSP RUNTIME" },
552*5f74217cSAbdelkader Boudih { CBMEM_ID_FSPM_VERSION, "FSPM VERSION" },
553*5f74217cSAbdelkader Boudih { CBMEM_ID_IGD_OPREGION, "IGD OPREGION" },
554*5f74217cSAbdelkader Boudih { CBMEM_ID_IMD_ROOT, "IMD ROOT" },
555*5f74217cSAbdelkader Boudih { CBMEM_ID_IMD_SMALL, "IMD SMALL" },
556*5f74217cSAbdelkader Boudih { CBMEM_ID_MEMINFO, "MEM INFO" },
557*5f74217cSAbdelkader Boudih { CBMEM_ID_MPTABLE, "SMP TABLE" },
558*5f74217cSAbdelkader Boudih { CBMEM_ID_MRCDATA, "MRC DATA" },
559*5f74217cSAbdelkader Boudih { CBMEM_ID_PIRQ, "IRQ TABLE" },
560*5f74217cSAbdelkader Boudih { CBMEM_ID_POWER_STATE, "POWER STATE" },
561*5f74217cSAbdelkader Boudih { CBMEM_ID_RAM_OOPS, "RAMOOPS" },
562*5f74217cSAbdelkader Boudih { CBMEM_ID_RAMSTAGE, "RAMSTAGE" },
563*5f74217cSAbdelkader Boudih { CBMEM_ID_REFCODE, "REFCODE" },
564*5f74217cSAbdelkader Boudih { CBMEM_ID_RESUME, "ACPI RESUME" },
565*5f74217cSAbdelkader Boudih { CBMEM_ID_ROMSTAGE_INFO, "ROMSTAGE" },
566*5f74217cSAbdelkader Boudih { CBMEM_ID_ROMSTAGE_RAM_STACK, "ROMSTG STACK" },
567*5f74217cSAbdelkader Boudih { CBMEM_ID_ROOT, "CBMEM ROOT" },
568*5f74217cSAbdelkader Boudih { CBMEM_ID_SMBIOS, "SMBIOS" },
569*5f74217cSAbdelkader Boudih { CBMEM_ID_SMM_COMBUFFER, "SMM COMBUF" },
570*5f74217cSAbdelkader Boudih { CBMEM_ID_SMM_SAVE_SPACE, "SMM BACKUP" },
571*5f74217cSAbdelkader Boudih { CBMEM_ID_TIMESTAMP, "TIMESTAMP" },
572*5f74217cSAbdelkader Boudih { CBMEM_ID_VBOOT_WORKBUF, "VBOOT WORK" },
573*5f74217cSAbdelkader Boudih { CBMEM_ID_VPD, "VPD" },
574*5f74217cSAbdelkader Boudih { 0, NULL }
575*5f74217cSAbdelkader Boudih };
576*5f74217cSAbdelkader Boudih
577*5f74217cSAbdelkader Boudih return (cb_id_lookup(names, id, "UNKNOWN"));
578*5f74217cSAbdelkader Boudih }
579*5f74217cSAbdelkader Boudih
580*5f74217cSAbdelkader Boudih /*
581*5f74217cSAbdelkader Boudih * IP-style 16-bit checksum (RFC 1071) over 16-bit words.
582*5f74217cSAbdelkader Boudih * When computed over data including its checksum field, result is 0.
583*5f74217cSAbdelkader Boudih */
584*5f74217cSAbdelkader Boudih static __inline uint16_t
cb_checksum(const void * ptr,size_t len)585*5f74217cSAbdelkader Boudih cb_checksum(const void *ptr, size_t len)
586*5f74217cSAbdelkader Boudih {
587*5f74217cSAbdelkader Boudih const uint8_t *p = (const uint8_t *)ptr;
588*5f74217cSAbdelkader Boudih uint32_t sum = 0;
589*5f74217cSAbdelkader Boudih size_t i;
590*5f74217cSAbdelkader Boudih
591*5f74217cSAbdelkader Boudih for (i = 0; i + 1 < len; i += 2)
592*5f74217cSAbdelkader Boudih sum += (uint32_t)p[i] | ((uint32_t)p[i + 1] << 8);
593*5f74217cSAbdelkader Boudih
594*5f74217cSAbdelkader Boudih if (i < len)
595*5f74217cSAbdelkader Boudih sum += p[i];
596*5f74217cSAbdelkader Boudih
597*5f74217cSAbdelkader Boudih while (sum >> 16)
598*5f74217cSAbdelkader Boudih sum = (sum & 0xffff) + (sum >> 16);
599*5f74217cSAbdelkader Boudih
600*5f74217cSAbdelkader Boudih return ((uint16_t)~sum);
601*5f74217cSAbdelkader Boudih }
602*5f74217cSAbdelkader Boudih
603*5f74217cSAbdelkader Boudih /*
604*5f74217cSAbdelkader Boudih * Destroy a character device and clear the pointer.
605*5f74217cSAbdelkader Boudih * Safe to call with a NULL cdev pointer.
606*5f74217cSAbdelkader Boudih */
607*5f74217cSAbdelkader Boudih static __inline void
coreboot_cdev_destroy(struct cdev ** cdevp)608*5f74217cSAbdelkader Boudih coreboot_cdev_destroy(struct cdev **cdevp)
609*5f74217cSAbdelkader Boudih {
610*5f74217cSAbdelkader Boudih
611*5f74217cSAbdelkader Boudih if (*cdevp != NULL) {
612*5f74217cSAbdelkader Boudih destroy_dev(*cdevp);
613*5f74217cSAbdelkader Boudih *cdevp = NULL;
614*5f74217cSAbdelkader Boudih }
615*5f74217cSAbdelkader Boudih }
616*5f74217cSAbdelkader Boudih
617*5f74217cSAbdelkader Boudih /* Functions exported from coreboot.c */
618*5f74217cSAbdelkader Boudih struct coreboot_softc *coreboot_get_softc(void);
619*5f74217cSAbdelkader Boudih
620*5f74217cSAbdelkader Boudih /* Functions exported from coreboot_console.c */
621*5f74217cSAbdelkader Boudih int coreboot_console_create(struct coreboot_softc *sc);
622*5f74217cSAbdelkader Boudih void coreboot_console_destroy(struct coreboot_softc *sc);
623*5f74217cSAbdelkader Boudih
624*5f74217cSAbdelkader Boudih /* Functions exported from coreboot_cbmem.c */
625*5f74217cSAbdelkader Boudih int coreboot_cbmem_create(struct coreboot_softc *sc);
626*5f74217cSAbdelkader Boudih void coreboot_cbmem_destroy(struct coreboot_softc *sc);
627*5f74217cSAbdelkader Boudih
628*5f74217cSAbdelkader Boudih /* Functions exported from coreboot_timestamps.c */
629*5f74217cSAbdelkader Boudih int coreboot_timestamps_register(struct coreboot_softc *sc,
630*5f74217cSAbdelkader Boudih struct sysctl_oid *parent);
631*5f74217cSAbdelkader Boudih
632*5f74217cSAbdelkader Boudih #endif /* _DEV_COREBOOT_COREBOOT_H_ */
633