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