aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpi_extlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpi_extlog.c')
-rw-r--r--drivers/acpi/acpi_extlog.c62
1 files changed, 12 insertions, 50 deletions
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 5d33c5415405..c4a5d87ede7e 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -9,7 +9,6 @@
9 9
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/acpi.h> 11#include <linux/acpi.h>
12#include <acpi/acpi_bus.h>
13#include <linux/cper.h> 12#include <linux/cper.h>
14#include <linux/ratelimit.h> 13#include <linux/ratelimit.h>
15#include <linux/edac.h> 14#include <linux/edac.h>
@@ -21,11 +20,9 @@
21#define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ 20#define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */
22 21
23#define EXTLOG_DSM_REV 0x0 22#define EXTLOG_DSM_REV 0x0
24#define EXTLOG_FN_QUERY 0x0
25#define EXTLOG_FN_ADDR 0x1 23#define EXTLOG_FN_ADDR 0x1
26 24
27#define FLAG_OS_OPTIN BIT(0) 25#define FLAG_OS_OPTIN BIT(0)
28#define EXTLOG_QUERY_L1_EXIST BIT(1)
29#define ELOG_ENTRY_VALID (1ULL<<63) 26#define ELOG_ENTRY_VALID (1ULL<<63)
30#define ELOG_ENTRY_LEN 0x1000 27#define ELOG_ENTRY_LEN 0x1000
31 28
@@ -46,7 +43,7 @@ struct extlog_l1_head {
46 43
47static int old_edac_report_status; 44static int old_edac_report_status;
48 45
49static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; 46static u8 extlog_dsm_uuid[] __initdata = "663E35AF-CC10-41A4-88EA-5470AF055295";
50 47
51/* L1 table related physical address */ 48/* L1 table related physical address */
52static u64 elog_base; 49static u64 elog_base;
@@ -156,62 +153,27 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
156 return NOTIFY_STOP; 153 return NOTIFY_STOP;
157} 154}
158 155
159static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret) 156static bool __init extlog_get_l1addr(void)
160{ 157{
161 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
162 struct acpi_object_list input;
163 union acpi_object params[4], *obj;
164 u8 uuid[16]; 158 u8 uuid[16];
165 int i; 159 acpi_handle handle;
160 union acpi_object *obj;
166 161
167 acpi_str_to_uuid(extlog_dsm_uuid, uuid); 162 acpi_str_to_uuid(extlog_dsm_uuid, uuid);
168 input.count = 4;
169 input.pointer = params;
170 params[0].type = ACPI_TYPE_BUFFER;
171 params[0].buffer.length = 16;
172 params[0].buffer.pointer = uuid;
173 params[1].type = ACPI_TYPE_INTEGER;
174 params[1].integer.value = rev;
175 params[2].type = ACPI_TYPE_INTEGER;
176 params[2].integer.value = func;
177 params[3].type = ACPI_TYPE_PACKAGE;
178 params[3].package.count = 0;
179 params[3].package.elements = NULL;
180
181 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf)))
182 return -1;
183
184 *ret = 0;
185 obj = (union acpi_object *)buf.pointer;
186 if (obj->type == ACPI_TYPE_INTEGER) {
187 *ret = obj->integer.value;
188 } else if (obj->type == ACPI_TYPE_BUFFER) {
189 if (obj->buffer.length <= 8) {
190 for (i = 0; i < obj->buffer.length; i++)
191 *ret |= (obj->buffer.pointer[i] << (i * 8));
192 }
193 }
194 kfree(buf.pointer);
195
196 return 0;
197}
198
199static bool extlog_get_l1addr(void)
200{
201 acpi_handle handle;
202 u64 ret;
203 163
204 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) 164 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
205 return false; 165 return false;
206 166 if (!acpi_check_dsm(handle, uuid, EXTLOG_DSM_REV, 1 << EXTLOG_FN_ADDR))
207 if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_QUERY, &ret) ||
208 !(ret & EXTLOG_QUERY_L1_EXIST))
209 return false; 167 return false;
210 168 obj = acpi_evaluate_dsm_typed(handle, uuid, EXTLOG_DSM_REV,
211 if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret)) 169 EXTLOG_FN_ADDR, NULL, ACPI_TYPE_INTEGER);
170 if (!obj) {
212 return false; 171 return false;
172 } else {
173 l1_dirbase = obj->integer.value;
174 ACPI_FREE(obj);
175 }
213 176
214 l1_dirbase = ret;
215 /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ 177 /* Spec says L1 directory must be 4K aligned, bail out if it isn't */
216 if (l1_dirbase & ((1 << 12) - 1)) { 178 if (l1_dirbase & ((1 << 12) - 1)) {
217 pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", 179 pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n",