16
16
#include <linux/acpi.h>
17
17
#include <linux/io.h>
18
18
#include <linux/pci.h>
19
+ #include <linux/efi.h>
19
20
20
21
int acpi_noirq = 1 ; /* skip ACPI IRQ initialization */
21
22
int acpi_disabled = 1 ;
@@ -24,6 +25,131 @@ EXPORT_SYMBOL(acpi_disabled);
24
25
int acpi_pci_disabled = 1 ; /* skip ACPI PCI scan and IRQ initialization */
25
26
EXPORT_SYMBOL (acpi_pci_disabled );
26
27
28
+ static bool param_acpi_off __initdata ;
29
+ static bool param_acpi_on __initdata ;
30
+ static bool param_acpi_force __initdata ;
31
+
32
+ static int __init parse_acpi (char * arg )
33
+ {
34
+ if (!arg )
35
+ return - EINVAL ;
36
+
37
+ /* "acpi=off" disables both ACPI table parsing and interpreter */
38
+ if (strcmp (arg , "off" ) == 0 )
39
+ param_acpi_off = true;
40
+ else if (strcmp (arg , "on" ) == 0 ) /* prefer ACPI over DT */
41
+ param_acpi_on = true;
42
+ else if (strcmp (arg , "force" ) == 0 ) /* force ACPI to be enabled */
43
+ param_acpi_force = true;
44
+ else
45
+ return - EINVAL ; /* Core will print when we return error */
46
+
47
+ return 0 ;
48
+ }
49
+ early_param ("acpi" , parse_acpi );
50
+
51
+ /*
52
+ * acpi_fadt_sanity_check() - Check FADT presence and carry out sanity
53
+ * checks on it
54
+ *
55
+ * Return 0 on success, <0 on failure
56
+ */
57
+ static int __init acpi_fadt_sanity_check (void )
58
+ {
59
+ struct acpi_table_header * table ;
60
+ struct acpi_table_fadt * fadt ;
61
+ acpi_status status ;
62
+ int ret = 0 ;
63
+
64
+ /*
65
+ * FADT is required on riscv; retrieve it to check its presence
66
+ * and carry out revision and ACPI HW reduced compliancy tests
67
+ */
68
+ status = acpi_get_table (ACPI_SIG_FADT , 0 , & table );
69
+ if (ACPI_FAILURE (status )) {
70
+ const char * msg = acpi_format_exception (status );
71
+
72
+ pr_err ("Failed to get FADT table, %s\n" , msg );
73
+ return - ENODEV ;
74
+ }
75
+
76
+ fadt = (struct acpi_table_fadt * )table ;
77
+
78
+ /*
79
+ * The revision in the table header is the FADT's Major revision. The
80
+ * FADT also has a minor revision, which is stored in the FADT itself.
81
+ *
82
+ * TODO: Currently, we check for 6.5 as the minimum version to check
83
+ * for HW_REDUCED flag. However, once RISC-V updates are released in
84
+ * the ACPI spec, we need to update this check for exact minor revision
85
+ */
86
+ if (table -> revision < 6 || (table -> revision == 6 && fadt -> minor_revision < 5 ))
87
+ pr_err (FW_BUG "Unsupported FADT revision %d.%d, should be 6.5+\n" ,
88
+ table -> revision , fadt -> minor_revision );
89
+
90
+ if (!(fadt -> flags & ACPI_FADT_HW_REDUCED )) {
91
+ pr_err ("FADT not ACPI hardware reduced compliant\n" );
92
+ ret = - EINVAL ;
93
+ }
94
+
95
+ /*
96
+ * acpi_get_table() creates FADT table mapping that
97
+ * should be released after parsing and before resuming boot
98
+ */
99
+ acpi_put_table (table );
100
+ return ret ;
101
+ }
102
+
103
+ /*
104
+ * acpi_boot_table_init() called from setup_arch(), always.
105
+ * 1. find RSDP and get its address, and then find XSDT
106
+ * 2. extract all tables and checksums them all
107
+ * 3. check ACPI FADT HW reduced flag
108
+ *
109
+ * We can parse ACPI boot-time tables such as MADT after
110
+ * this function is called.
111
+ *
112
+ * On return ACPI is enabled if either:
113
+ *
114
+ * - ACPI tables are initialized and sanity checks passed
115
+ * - acpi=force was passed in the command line and ACPI was not disabled
116
+ * explicitly through acpi=off command line parameter
117
+ *
118
+ * ACPI is disabled on function return otherwise
119
+ */
120
+ void __init acpi_boot_table_init (void )
121
+ {
122
+ /*
123
+ * Enable ACPI instead of device tree unless
124
+ * - ACPI has been disabled explicitly (acpi=off), or
125
+ * - firmware has not populated ACPI ptr in EFI system table
126
+ * and ACPI has not been [force] enabled (acpi=on|force)
127
+ */
128
+ if (param_acpi_off ||
129
+ (!param_acpi_on && !param_acpi_force &&
130
+ efi .acpi20 == EFI_INVALID_TABLE_ADDR ))
131
+ return ;
132
+
133
+ /*
134
+ * ACPI is disabled at this point. Enable it in order to parse
135
+ * the ACPI tables and carry out sanity checks
136
+ */
137
+ enable_acpi ();
138
+
139
+ /*
140
+ * If ACPI tables are initialized and FADT sanity checks passed,
141
+ * leave ACPI enabled and carry on booting; otherwise disable ACPI
142
+ * on initialization error.
143
+ * If acpi=force was passed on the command line it forces ACPI
144
+ * to be enabled even if its initialization failed.
145
+ */
146
+ if (acpi_table_init () || acpi_fadt_sanity_check ()) {
147
+ pr_err ("Failed to init ACPI tables\n" );
148
+ if (!param_acpi_force )
149
+ disable_acpi ();
150
+ }
151
+ }
152
+
27
153
/*
28
154
* __acpi_map_table() will be called before paging_init(), so early_ioremap()
29
155
* or early_memremap() should be called here to for ACPI table mapping.
0 commit comments