1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
7 static void fill_x_pm_io(acpi_addr_t
*x_pm_blk
, int access_size
, uint16_t ioport
, uint8_t len
)
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;
17 static void do_sanity_error(const char *func
, const int line
)
19 printk(BIOS_ERR
, "ACPI: FADT error detected, %s line %d.\n", func
, line
);
22 #define fadt_sanity(x) do { if (!(x)) do_sanity_error(__func__, __LINE__); } while (0)
24 void fill_fadt_extended_pm_io(acpi_fadt_t
*fadt
)
26 fadt_sanity(fadt
->pm1a_evt_blk
&& (fadt
->pm1_evt_len
>= 4));
28 /* Upper word is reserved and Linux complains about 32 bit. */
29 fadt_sanity(fadt
->pm1a_cnt_blk
&& (fadt
->pm1_cnt_len
== 2));
31 fill_x_pm_io(&fadt
->x_pm1a_evt_blk
, ACPI_ACCESS_SIZE_WORD_ACCESS
,
32 fadt
->pm1a_evt_blk
, fadt
->pm1_evt_len
);
34 fill_x_pm_io(&fadt
->x_pm1a_cnt_blk
, ACPI_ACCESS_SIZE_WORD_ACCESS
,
35 fadt
->pm1a_cnt_blk
, fadt
->pm1_cnt_len
);
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
);
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
);
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
);
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
);
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.
61 * FIXME: GPE1_BASE is not initialised.
66 fill_x_pm_io(&fadt
->x_gpe0_blk
, ACPI_ACCESS_SIZE_BYTE_ACCESS
,
67 fadt
->gpe0_blk
, fadt
->gpe0_blk_len
);
70 fill_x_pm_io(&fadt
->x_gpe1_blk
, ACPI_ACCESS_SIZE_BYTE_ACCESS
,
71 fadt
->gpe1_blk
, fadt
->gpe1_blk_len
);