xref: /aosp_15_r20/external/coreboot/src/acpi/fadt_filler.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <console/console.h>
5 #include <stdint.h>
6 
fill_x_pm_io(acpi_addr_t * x_pm_blk,int access_size,uint16_t ioport,uint8_t len)7 static void fill_x_pm_io(acpi_addr_t *x_pm_blk, int access_size, uint16_t ioport, uint8_t len)
8 {
9 	x_pm_blk->space_id = ACPI_ADDRESS_SPACE_IO;
10 	x_pm_blk->bit_width = len * 8;
11 	x_pm_blk->bit_offset = 0;
12 	x_pm_blk->access_size = access_size;
13 	x_pm_blk->addrl = ioport;
14 	x_pm_blk->addrh = 0x0;
15 }
16 
do_sanity_error(const char * func,const int line)17 static void do_sanity_error(const char *func, const int line)
18 {
19 	printk(BIOS_ERR, "ACPI: FADT error detected, %s line %d.\n", func, line);
20 }
21 
22 #define fadt_sanity(x)	do { if (!(x)) do_sanity_error(__func__, __LINE__); } while (0)
23 
fill_fadt_extended_pm_io(acpi_fadt_t * fadt)24 void fill_fadt_extended_pm_io(acpi_fadt_t *fadt)
25 {
26 	fadt_sanity(fadt->pm1a_evt_blk && (fadt->pm1_evt_len >= 4));
27 
28 	/* Upper word is reserved and Linux complains about 32 bit. */
29 	fadt_sanity(fadt->pm1a_cnt_blk && (fadt->pm1_cnt_len == 2));
30 
31 	fill_x_pm_io(&fadt->x_pm1a_evt_blk, ACPI_ACCESS_SIZE_WORD_ACCESS,
32 		     fadt->pm1a_evt_blk, fadt->pm1_evt_len);
33 
34 	fill_x_pm_io(&fadt->x_pm1a_cnt_blk, ACPI_ACCESS_SIZE_WORD_ACCESS,
35 		     fadt->pm1a_cnt_blk, fadt->pm1_cnt_len);
36 
37 	if (fadt->pm1b_evt_blk)
38 		fill_x_pm_io(&fadt->x_pm1b_evt_blk, ACPI_ACCESS_SIZE_WORD_ACCESS,
39 			     fadt->pm1b_evt_blk, fadt->pm1_evt_len);
40 
41 	if (fadt->pm1b_cnt_blk)
42 		fill_x_pm_io(&fadt->x_pm1b_cnt_blk, ACPI_ACCESS_SIZE_WORD_ACCESS,
43 			     fadt->pm1b_cnt_blk, fadt->pm1_cnt_len);
44 
45 	if (fadt->pm_tmr_blk) {
46 		fadt_sanity(fadt->pm_tmr_len == 4);
47 		fill_x_pm_io(&fadt->x_pm_tmr_blk, ACPI_ACCESS_SIZE_DWORD_ACCESS,
48 			     fadt->pm_tmr_blk, fadt->pm_tmr_len);
49 	}
50 
51 	if (fadt->pm2_cnt_blk)
52 		fill_x_pm_io(&fadt->x_pm2_cnt_blk, ACPI_ACCESS_SIZE_BYTE_ACCESS,
53 			     fadt->pm2_cnt_blk, fadt->pm2_cnt_len);
54 
55 	/*
56 	 * Windows 10 requires x_gpe0_blk to be set starting with FADT revision 5.
57 	 * The bit_width field intentionally overflows here.
58 	 * The OSPM can instead use the values in `fadt->gpe0_blk{,_len}`, which
59 	 * seems to work fine on Linux 5.0 and Windows 10.
60 	 *
61 	 * FIXME: GPE1_BASE is not initialised.
62 	 *
63 	 */
64 
65 	if (fadt->gpe0_blk)
66 		fill_x_pm_io(&fadt->x_gpe0_blk, ACPI_ACCESS_SIZE_BYTE_ACCESS,
67 			     fadt->gpe0_blk, fadt->gpe0_blk_len);
68 
69 	if (fadt->gpe1_blk)
70 		fill_x_pm_io(&fadt->x_gpe1_blk, ACPI_ACCESS_SIZE_BYTE_ACCESS,
71 			     fadt->gpe1_blk, fadt->gpe1_blk_len);
72 }
73