xref: /linux/drivers/firmware/coreboot/gsmi.c (revision 9e947d96915af63e28896caae85a81b74855621b)
1*44e33a5aSSean Rhodes // SPDX-License-Identifier: GPL-2.0-only
2*44e33a5aSSean Rhodes /*
3*44e33a5aSSean Rhodes  * Copyright 2010 Google Inc. All Rights Reserved.
4*44e33a5aSSean Rhodes  * Author: dlaurie@google.com (Duncan Laurie)
5*44e33a5aSSean Rhodes  *
6*44e33a5aSSean Rhodes  * Re-worked to expose sysfs APIs by mikew@google.com (Mike Waychison)
7*44e33a5aSSean Rhodes  *
8*44e33a5aSSean Rhodes  * EFI SMI interface for Google platforms
9*44e33a5aSSean Rhodes  */
10*44e33a5aSSean Rhodes 
11*44e33a5aSSean Rhodes #include <linux/kernel.h>
12*44e33a5aSSean Rhodes #include <linux/init.h>
13*44e33a5aSSean Rhodes #include <linux/types.h>
14*44e33a5aSSean Rhodes #include <linux/device.h>
15*44e33a5aSSean Rhodes #include <linux/platform_device.h>
16*44e33a5aSSean Rhodes #include <linux/errno.h>
17*44e33a5aSSean Rhodes #include <linux/string.h>
18*44e33a5aSSean Rhodes #include <linux/spinlock.h>
19*44e33a5aSSean Rhodes #include <linux/dma-mapping.h>
20*44e33a5aSSean Rhodes #include <linux/fs.h>
21*44e33a5aSSean Rhodes #include <linux/slab.h>
22*44e33a5aSSean Rhodes #include <linux/panic_notifier.h>
23*44e33a5aSSean Rhodes #include <linux/ioctl.h>
24*44e33a5aSSean Rhodes #include <linux/acpi.h>
25*44e33a5aSSean Rhodes #include <linux/io.h>
26*44e33a5aSSean Rhodes #include <linux/uaccess.h>
27*44e33a5aSSean Rhodes #include <linux/dmi.h>
28*44e33a5aSSean Rhodes #include <linux/kdebug.h>
29*44e33a5aSSean Rhodes #include <linux/reboot.h>
30*44e33a5aSSean Rhodes #include <linux/efi.h>
31*44e33a5aSSean Rhodes #include <linux/module.h>
32*44e33a5aSSean Rhodes #include <linux/ucs2_string.h>
33*44e33a5aSSean Rhodes #include <linux/suspend.h>
34*44e33a5aSSean Rhodes 
35*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_CLEAN	0	/* Clean Shutdown */
36*44e33a5aSSean Rhodes /* TODO(mikew@google.com): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
37*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_NMIWDT	1	/* NMI Watchdog */
38*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_PANIC	2	/* Panic */
39*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_OOPS	3	/* Oops */
40*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_DIE	4	/* Die -- No longer meaningful */
41*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_MCE	5	/* Machine Check */
42*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_SOFTWDT	6	/* Software Watchdog */
43*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_MBE	7	/* Uncorrected ECC */
44*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_TRIPLE	8	/* Triple Fault */
45*44e33a5aSSean Rhodes 
46*44e33a5aSSean Rhodes #define DRIVER_VERSION		"1.0"
47*44e33a5aSSean Rhodes #define GSMI_GUID_SIZE		16
48*44e33a5aSSean Rhodes #define GSMI_BUF_SIZE		1024
49*44e33a5aSSean Rhodes #define GSMI_BUF_ALIGN		sizeof(u64)
50*44e33a5aSSean Rhodes #define GSMI_CALLBACK		0xef
51*44e33a5aSSean Rhodes 
52*44e33a5aSSean Rhodes /* SMI return codes */
53*44e33a5aSSean Rhodes #define GSMI_SUCCESS		0x00
54*44e33a5aSSean Rhodes #define GSMI_UNSUPPORTED2	0x03
55*44e33a5aSSean Rhodes #define GSMI_LOG_FULL		0x0b
56*44e33a5aSSean Rhodes #define GSMI_VAR_NOT_FOUND	0x0e
57*44e33a5aSSean Rhodes #define GSMI_HANDSHAKE_SPIN	0x7d
58*44e33a5aSSean Rhodes #define GSMI_HANDSHAKE_CF	0x7e
59*44e33a5aSSean Rhodes #define GSMI_HANDSHAKE_NONE	0x7f
60*44e33a5aSSean Rhodes #define GSMI_INVALID_PARAMETER	0x82
61*44e33a5aSSean Rhodes #define GSMI_UNSUPPORTED	0x83
62*44e33a5aSSean Rhodes #define GSMI_BUFFER_TOO_SMALL	0x85
63*44e33a5aSSean Rhodes #define GSMI_NOT_READY		0x86
64*44e33a5aSSean Rhodes #define GSMI_DEVICE_ERROR	0x87
65*44e33a5aSSean Rhodes #define GSMI_NOT_FOUND		0x8e
66*44e33a5aSSean Rhodes 
67*44e33a5aSSean Rhodes #define QUIRKY_BOARD_HASH 0x78a30a50
68*44e33a5aSSean Rhodes 
69*44e33a5aSSean Rhodes /* Internally used commands passed to the firmware */
70*44e33a5aSSean Rhodes #define GSMI_CMD_GET_NVRAM_VAR		0x01
71*44e33a5aSSean Rhodes #define GSMI_CMD_GET_NEXT_VAR		0x02
72*44e33a5aSSean Rhodes #define GSMI_CMD_SET_NVRAM_VAR		0x03
73*44e33a5aSSean Rhodes #define GSMI_CMD_SET_EVENT_LOG		0x08
74*44e33a5aSSean Rhodes #define GSMI_CMD_CLEAR_EVENT_LOG	0x09
75*44e33a5aSSean Rhodes #define GSMI_CMD_LOG_S0IX_SUSPEND	0x0a
76*44e33a5aSSean Rhodes #define GSMI_CMD_LOG_S0IX_RESUME	0x0b
77*44e33a5aSSean Rhodes #define GSMI_CMD_CLEAR_CONFIG		0x20
78*44e33a5aSSean Rhodes #define GSMI_CMD_HANDSHAKE_TYPE		0xC1
79*44e33a5aSSean Rhodes #define GSMI_CMD_RESERVED		0xff
80*44e33a5aSSean Rhodes 
81*44e33a5aSSean Rhodes /* Magic entry type for kernel events */
82*44e33a5aSSean Rhodes #define GSMI_LOG_ENTRY_TYPE_KERNEL     0xDEAD
83*44e33a5aSSean Rhodes 
84*44e33a5aSSean Rhodes /* SMI buffers must be in 32bit physical address space */
85*44e33a5aSSean Rhodes struct gsmi_buf {
86*44e33a5aSSean Rhodes 	u8 *start;			/* start of buffer */
87*44e33a5aSSean Rhodes 	size_t length;			/* length of buffer */
88*44e33a5aSSean Rhodes 	u32 address;			/* physical address of buffer */
89*44e33a5aSSean Rhodes };
90*44e33a5aSSean Rhodes 
91*44e33a5aSSean Rhodes static struct gsmi_device {
92*44e33a5aSSean Rhodes 	struct platform_device *pdev;	/* platform device */
93*44e33a5aSSean Rhodes 	struct gsmi_buf *name_buf;	/* variable name buffer */
94*44e33a5aSSean Rhodes 	struct gsmi_buf *data_buf;	/* generic data buffer */
95*44e33a5aSSean Rhodes 	struct gsmi_buf *param_buf;	/* parameter buffer */
96*44e33a5aSSean Rhodes 	spinlock_t lock;		/* serialize access to SMIs */
97*44e33a5aSSean Rhodes 	u16 smi_cmd;			/* SMI command port */
98*44e33a5aSSean Rhodes 	int handshake_type;		/* firmware handler interlock type */
99*44e33a5aSSean Rhodes 	struct kmem_cache *mem_pool;	/* kmem cache for gsmi_buf allocations */
100*44e33a5aSSean Rhodes } gsmi_dev;
101*44e33a5aSSean Rhodes 
102*44e33a5aSSean Rhodes /* Packed structures for communicating with the firmware */
103*44e33a5aSSean Rhodes struct gsmi_nvram_var_param {
104*44e33a5aSSean Rhodes 	efi_guid_t	guid;
105*44e33a5aSSean Rhodes 	u32		name_ptr;
106*44e33a5aSSean Rhodes 	u32		attributes;
107*44e33a5aSSean Rhodes 	u32		data_len;
108*44e33a5aSSean Rhodes 	u32		data_ptr;
109*44e33a5aSSean Rhodes } __packed;
110*44e33a5aSSean Rhodes 
111*44e33a5aSSean Rhodes struct gsmi_get_next_var_param {
112*44e33a5aSSean Rhodes 	u8	guid[GSMI_GUID_SIZE];
113*44e33a5aSSean Rhodes 	u32	name_ptr;
114*44e33a5aSSean Rhodes 	u32	name_len;
115*44e33a5aSSean Rhodes } __packed;
116*44e33a5aSSean Rhodes 
117*44e33a5aSSean Rhodes struct gsmi_set_eventlog_param {
118*44e33a5aSSean Rhodes 	u32	data_ptr;
119*44e33a5aSSean Rhodes 	u32	data_len;
120*44e33a5aSSean Rhodes 	u32	type;
121*44e33a5aSSean Rhodes } __packed;
122*44e33a5aSSean Rhodes 
123*44e33a5aSSean Rhodes /* Event log formats */
124*44e33a5aSSean Rhodes struct gsmi_log_entry_type_1 {
125*44e33a5aSSean Rhodes 	u16	type;
126*44e33a5aSSean Rhodes 	u32	instance;
127*44e33a5aSSean Rhodes } __packed;
128*44e33a5aSSean Rhodes 
129*44e33a5aSSean Rhodes /*
130*44e33a5aSSean Rhodes  * Some platforms don't have explicit SMI handshake
131*44e33a5aSSean Rhodes  * and need to wait for SMI to complete.
132*44e33a5aSSean Rhodes  */
133*44e33a5aSSean Rhodes #define GSMI_DEFAULT_SPINCOUNT	0x10000
134*44e33a5aSSean Rhodes static unsigned int spincount = GSMI_DEFAULT_SPINCOUNT;
135*44e33a5aSSean Rhodes module_param(spincount, uint, 0600);
136*44e33a5aSSean Rhodes MODULE_PARM_DESC(spincount,
137*44e33a5aSSean Rhodes 	"The number of loop iterations to use when using the spin handshake.");
138*44e33a5aSSean Rhodes 
139*44e33a5aSSean Rhodes /*
140*44e33a5aSSean Rhodes  * Some older platforms with Apollo Lake chipsets do not support S0ix logging
141*44e33a5aSSean Rhodes  * in their GSMI handlers, and behaved poorly when resuming via power button
142*44e33a5aSSean Rhodes  * press if the logging was attempted. Updated firmware with proper behavior
143*44e33a5aSSean Rhodes  * has long since shipped, removing the need for this opt-in parameter. It
144*44e33a5aSSean Rhodes  * now exists as an opt-out parameter for folks defiantly running old
145*44e33a5aSSean Rhodes  * firmware, or unforeseen circumstances. After the change from opt-in to
146*44e33a5aSSean Rhodes  * opt-out has baked sufficiently, this parameter should probably be removed
147*44e33a5aSSean Rhodes  * entirely.
148*44e33a5aSSean Rhodes  */
149*44e33a5aSSean Rhodes static bool s0ix_logging_enable = true;
150*44e33a5aSSean Rhodes module_param(s0ix_logging_enable, bool, 0600);
151*44e33a5aSSean Rhodes 
gsmi_buf_alloc(void)152*44e33a5aSSean Rhodes static struct gsmi_buf *gsmi_buf_alloc(void)
153*44e33a5aSSean Rhodes {
154*44e33a5aSSean Rhodes 	struct gsmi_buf *smibuf;
155*44e33a5aSSean Rhodes 
156*44e33a5aSSean Rhodes 	smibuf = kzalloc_obj(*smibuf);
157*44e33a5aSSean Rhodes 	if (!smibuf) {
158*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: out of memory\n");
159*44e33a5aSSean Rhodes 		return NULL;
160*44e33a5aSSean Rhodes 	}
161*44e33a5aSSean Rhodes 
162*44e33a5aSSean Rhodes 	/* allocate buffer in 32bit address space */
163*44e33a5aSSean Rhodes 	smibuf->start = kmem_cache_alloc(gsmi_dev.mem_pool, GFP_KERNEL);
164*44e33a5aSSean Rhodes 	if (!smibuf->start) {
165*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
166*44e33a5aSSean Rhodes 		kfree(smibuf);
167*44e33a5aSSean Rhodes 		return NULL;
168*44e33a5aSSean Rhodes 	}
169*44e33a5aSSean Rhodes 
170*44e33a5aSSean Rhodes 	/* fill in the buffer handle */
171*44e33a5aSSean Rhodes 	smibuf->length = GSMI_BUF_SIZE;
172*44e33a5aSSean Rhodes 	smibuf->address = (u32)virt_to_phys(smibuf->start);
173*44e33a5aSSean Rhodes 
174*44e33a5aSSean Rhodes 	return smibuf;
175*44e33a5aSSean Rhodes }
176*44e33a5aSSean Rhodes 
gsmi_buf_free(struct gsmi_buf * smibuf)177*44e33a5aSSean Rhodes static void gsmi_buf_free(struct gsmi_buf *smibuf)
178*44e33a5aSSean Rhodes {
179*44e33a5aSSean Rhodes 	if (smibuf) {
180*44e33a5aSSean Rhodes 		if (smibuf->start)
181*44e33a5aSSean Rhodes 			kmem_cache_free(gsmi_dev.mem_pool, smibuf->start);
182*44e33a5aSSean Rhodes 		kfree(smibuf);
183*44e33a5aSSean Rhodes 	}
184*44e33a5aSSean Rhodes }
185*44e33a5aSSean Rhodes 
186*44e33a5aSSean Rhodes /*
187*44e33a5aSSean Rhodes  * Make a call to gsmi func(sub).  GSMI error codes are translated to
188*44e33a5aSSean Rhodes  * in-kernel errnos (0 on success, -ERRNO on error).
189*44e33a5aSSean Rhodes  */
gsmi_exec(u8 func,u8 sub)190*44e33a5aSSean Rhodes static int gsmi_exec(u8 func, u8 sub)
191*44e33a5aSSean Rhodes {
192*44e33a5aSSean Rhodes 	u16 cmd = (sub << 8) | func;
193*44e33a5aSSean Rhodes 	u16 result = 0;
194*44e33a5aSSean Rhodes 	int rc = 0;
195*44e33a5aSSean Rhodes 
196*44e33a5aSSean Rhodes 	/*
197*44e33a5aSSean Rhodes 	 * AH  : Subfunction number
198*44e33a5aSSean Rhodes 	 * AL  : Function number
199*44e33a5aSSean Rhodes 	 * EBX : Parameter block address
200*44e33a5aSSean Rhodes 	 * DX  : SMI command port
201*44e33a5aSSean Rhodes 	 *
202*44e33a5aSSean Rhodes 	 * Three protocols here. See also the comment in gsmi_init().
203*44e33a5aSSean Rhodes 	 */
204*44e33a5aSSean Rhodes 	if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_CF) {
205*44e33a5aSSean Rhodes 		/*
206*44e33a5aSSean Rhodes 		 * If handshake_type == HANDSHAKE_CF then set CF on the
207*44e33a5aSSean Rhodes 		 * way in and wait for the handler to clear it; this avoids
208*44e33a5aSSean Rhodes 		 * corrupting register state on those chipsets which have
209*44e33a5aSSean Rhodes 		 * a delay between writing the SMI trigger register and
210*44e33a5aSSean Rhodes 		 * entering SMM.
211*44e33a5aSSean Rhodes 		 */
212*44e33a5aSSean Rhodes 		asm volatile (
213*44e33a5aSSean Rhodes 			"stc\n"
214*44e33a5aSSean Rhodes 			"outb %%al, %%dx\n"
215*44e33a5aSSean Rhodes 		"1:      jc 1b\n"
216*44e33a5aSSean Rhodes 			: "=a" (result)
217*44e33a5aSSean Rhodes 			: "0" (cmd),
218*44e33a5aSSean Rhodes 			  "d" (gsmi_dev.smi_cmd),
219*44e33a5aSSean Rhodes 			  "b" (gsmi_dev.param_buf->address)
220*44e33a5aSSean Rhodes 			: "memory", "cc"
221*44e33a5aSSean Rhodes 		);
222*44e33a5aSSean Rhodes 	} else if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_SPIN) {
223*44e33a5aSSean Rhodes 		/*
224*44e33a5aSSean Rhodes 		 * If handshake_type == HANDSHAKE_SPIN we spin a
225*44e33a5aSSean Rhodes 		 * hundred-ish usecs to ensure the SMI has triggered.
226*44e33a5aSSean Rhodes 		 */
227*44e33a5aSSean Rhodes 		asm volatile (
228*44e33a5aSSean Rhodes 			"outb %%al, %%dx\n"
229*44e33a5aSSean Rhodes 		"1:      loop 1b\n"
230*44e33a5aSSean Rhodes 			: "=a" (result)
231*44e33a5aSSean Rhodes 			: "0" (cmd),
232*44e33a5aSSean Rhodes 			  "d" (gsmi_dev.smi_cmd),
233*44e33a5aSSean Rhodes 			  "b" (gsmi_dev.param_buf->address),
234*44e33a5aSSean Rhodes 			  "c" (spincount)
235*44e33a5aSSean Rhodes 			: "memory", "cc"
236*44e33a5aSSean Rhodes 		);
237*44e33a5aSSean Rhodes 	} else {
238*44e33a5aSSean Rhodes 		/*
239*44e33a5aSSean Rhodes 		 * If handshake_type == HANDSHAKE_NONE we do nothing;
240*44e33a5aSSean Rhodes 		 * either we don't need to or it's legacy firmware that
241*44e33a5aSSean Rhodes 		 * doesn't understand the CF protocol.
242*44e33a5aSSean Rhodes 		 */
243*44e33a5aSSean Rhodes 		asm volatile (
244*44e33a5aSSean Rhodes 			"outb %%al, %%dx\n\t"
245*44e33a5aSSean Rhodes 			: "=a" (result)
246*44e33a5aSSean Rhodes 			: "0" (cmd),
247*44e33a5aSSean Rhodes 			  "d" (gsmi_dev.smi_cmd),
248*44e33a5aSSean Rhodes 			  "b" (gsmi_dev.param_buf->address)
249*44e33a5aSSean Rhodes 			: "memory", "cc"
250*44e33a5aSSean Rhodes 		);
251*44e33a5aSSean Rhodes 	}
252*44e33a5aSSean Rhodes 
253*44e33a5aSSean Rhodes 	/* check return code from SMI handler */
254*44e33a5aSSean Rhodes 	switch (result) {
255*44e33a5aSSean Rhodes 	case GSMI_SUCCESS:
256*44e33a5aSSean Rhodes 		break;
257*44e33a5aSSean Rhodes 	case GSMI_VAR_NOT_FOUND:
258*44e33a5aSSean Rhodes 		/* not really an error, but let the caller know */
259*44e33a5aSSean Rhodes 		rc = 1;
260*44e33a5aSSean Rhodes 		break;
261*44e33a5aSSean Rhodes 	case GSMI_INVALID_PARAMETER:
262*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: exec 0x%04x: Invalid parameter\n", cmd);
263*44e33a5aSSean Rhodes 		rc = -EINVAL;
264*44e33a5aSSean Rhodes 		break;
265*44e33a5aSSean Rhodes 	case GSMI_BUFFER_TOO_SMALL:
266*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: exec 0x%04x: Buffer too small\n", cmd);
267*44e33a5aSSean Rhodes 		rc = -ENOMEM;
268*44e33a5aSSean Rhodes 		break;
269*44e33a5aSSean Rhodes 	case GSMI_UNSUPPORTED:
270*44e33a5aSSean Rhodes 	case GSMI_UNSUPPORTED2:
271*44e33a5aSSean Rhodes 		if (sub != GSMI_CMD_HANDSHAKE_TYPE)
272*44e33a5aSSean Rhodes 			printk(KERN_ERR "gsmi: exec 0x%04x: Not supported\n",
273*44e33a5aSSean Rhodes 			       cmd);
274*44e33a5aSSean Rhodes 		rc = -ENOSYS;
275*44e33a5aSSean Rhodes 		break;
276*44e33a5aSSean Rhodes 	case GSMI_NOT_READY:
277*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: exec 0x%04x: Not ready\n", cmd);
278*44e33a5aSSean Rhodes 		rc = -EBUSY;
279*44e33a5aSSean Rhodes 		break;
280*44e33a5aSSean Rhodes 	case GSMI_DEVICE_ERROR:
281*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: exec 0x%04x: Device error\n", cmd);
282*44e33a5aSSean Rhodes 		rc = -EFAULT;
283*44e33a5aSSean Rhodes 		break;
284*44e33a5aSSean Rhodes 	case GSMI_NOT_FOUND:
285*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: exec 0x%04x: Data not found\n", cmd);
286*44e33a5aSSean Rhodes 		rc = -ENOENT;
287*44e33a5aSSean Rhodes 		break;
288*44e33a5aSSean Rhodes 	case GSMI_LOG_FULL:
289*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: exec 0x%04x: Log full\n", cmd);
290*44e33a5aSSean Rhodes 		rc = -ENOSPC;
291*44e33a5aSSean Rhodes 		break;
292*44e33a5aSSean Rhodes 	case GSMI_HANDSHAKE_CF:
293*44e33a5aSSean Rhodes 	case GSMI_HANDSHAKE_SPIN:
294*44e33a5aSSean Rhodes 	case GSMI_HANDSHAKE_NONE:
295*44e33a5aSSean Rhodes 		rc = result;
296*44e33a5aSSean Rhodes 		break;
297*44e33a5aSSean Rhodes 	default:
298*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: exec 0x%04x: Unknown error 0x%04x\n",
299*44e33a5aSSean Rhodes 		       cmd, result);
300*44e33a5aSSean Rhodes 		rc = -ENXIO;
301*44e33a5aSSean Rhodes 	}
302*44e33a5aSSean Rhodes 
303*44e33a5aSSean Rhodes 	return rc;
304*44e33a5aSSean Rhodes }
305*44e33a5aSSean Rhodes 
306*44e33a5aSSean Rhodes #ifdef CONFIG_EFI
307*44e33a5aSSean Rhodes 
308*44e33a5aSSean Rhodes static struct efivars efivars;
309*44e33a5aSSean Rhodes 
gsmi_get_variable(efi_char16_t * name,efi_guid_t * vendor,u32 * attr,unsigned long * data_size,void * data)310*44e33a5aSSean Rhodes static efi_status_t gsmi_get_variable(efi_char16_t *name,
311*44e33a5aSSean Rhodes 				      efi_guid_t *vendor, u32 *attr,
312*44e33a5aSSean Rhodes 				      unsigned long *data_size,
313*44e33a5aSSean Rhodes 				      void *data)
314*44e33a5aSSean Rhodes {
315*44e33a5aSSean Rhodes 	struct gsmi_nvram_var_param param = {
316*44e33a5aSSean Rhodes 		.name_ptr = gsmi_dev.name_buf->address,
317*44e33a5aSSean Rhodes 		.data_ptr = gsmi_dev.data_buf->address,
318*44e33a5aSSean Rhodes 		.data_len = (u32)*data_size,
319*44e33a5aSSean Rhodes 	};
320*44e33a5aSSean Rhodes 	efi_status_t ret = EFI_SUCCESS;
321*44e33a5aSSean Rhodes 	unsigned long flags;
322*44e33a5aSSean Rhodes 	size_t name_len = ucs2_strnlen(name, GSMI_BUF_SIZE / 2);
323*44e33a5aSSean Rhodes 	int rc;
324*44e33a5aSSean Rhodes 
325*44e33a5aSSean Rhodes 	if (name_len >= GSMI_BUF_SIZE / 2)
326*44e33a5aSSean Rhodes 		return EFI_BAD_BUFFER_SIZE;
327*44e33a5aSSean Rhodes 
328*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
329*44e33a5aSSean Rhodes 
330*44e33a5aSSean Rhodes 	/* Vendor guid */
331*44e33a5aSSean Rhodes 	memcpy(&param.guid, vendor, sizeof(param.guid));
332*44e33a5aSSean Rhodes 
333*44e33a5aSSean Rhodes 	/* variable name, already in UTF-16 */
334*44e33a5aSSean Rhodes 	memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
335*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
336*44e33a5aSSean Rhodes 
337*44e33a5aSSean Rhodes 	/* data pointer */
338*44e33a5aSSean Rhodes 	memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
339*44e33a5aSSean Rhodes 
340*44e33a5aSSean Rhodes 	/* parameter buffer */
341*44e33a5aSSean Rhodes 	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
342*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
343*44e33a5aSSean Rhodes 
344*44e33a5aSSean Rhodes 	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NVRAM_VAR);
345*44e33a5aSSean Rhodes 	if (rc < 0) {
346*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: Get Variable failed\n");
347*44e33a5aSSean Rhodes 		ret = EFI_LOAD_ERROR;
348*44e33a5aSSean Rhodes 	} else if (rc == 1) {
349*44e33a5aSSean Rhodes 		/* variable was not found */
350*44e33a5aSSean Rhodes 		ret = EFI_NOT_FOUND;
351*44e33a5aSSean Rhodes 	} else {
352*44e33a5aSSean Rhodes 		/* Get the arguments back */
353*44e33a5aSSean Rhodes 		memcpy(&param, gsmi_dev.param_buf->start, sizeof(param));
354*44e33a5aSSean Rhodes 
355*44e33a5aSSean Rhodes 		/* The size reported is the min of all of our buffers */
356*44e33a5aSSean Rhodes 		*data_size = min_t(unsigned long, *data_size,
357*44e33a5aSSean Rhodes 						gsmi_dev.data_buf->length);
358*44e33a5aSSean Rhodes 		*data_size = min_t(unsigned long, *data_size, param.data_len);
359*44e33a5aSSean Rhodes 
360*44e33a5aSSean Rhodes 		/* Copy data back to return buffer. */
361*44e33a5aSSean Rhodes 		memcpy(data, gsmi_dev.data_buf->start, *data_size);
362*44e33a5aSSean Rhodes 
363*44e33a5aSSean Rhodes 		/* All variables are have the following attributes */
364*44e33a5aSSean Rhodes 		if (attr)
365*44e33a5aSSean Rhodes 			*attr = EFI_VARIABLE_NON_VOLATILE |
366*44e33a5aSSean Rhodes 				EFI_VARIABLE_BOOTSERVICE_ACCESS |
367*44e33a5aSSean Rhodes 				EFI_VARIABLE_RUNTIME_ACCESS;
368*44e33a5aSSean Rhodes 	}
369*44e33a5aSSean Rhodes 
370*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
371*44e33a5aSSean Rhodes 
372*44e33a5aSSean Rhodes 	return ret;
373*44e33a5aSSean Rhodes }
374*44e33a5aSSean Rhodes 
gsmi_get_next_variable(unsigned long * name_size,efi_char16_t * name,efi_guid_t * vendor)375*44e33a5aSSean Rhodes static efi_status_t gsmi_get_next_variable(unsigned long *name_size,
376*44e33a5aSSean Rhodes 					   efi_char16_t *name,
377*44e33a5aSSean Rhodes 					   efi_guid_t *vendor)
378*44e33a5aSSean Rhodes {
379*44e33a5aSSean Rhodes 	struct gsmi_get_next_var_param param = {
380*44e33a5aSSean Rhodes 		.name_ptr = gsmi_dev.name_buf->address,
381*44e33a5aSSean Rhodes 		.name_len = gsmi_dev.name_buf->length,
382*44e33a5aSSean Rhodes 	};
383*44e33a5aSSean Rhodes 	efi_status_t ret = EFI_SUCCESS;
384*44e33a5aSSean Rhodes 	int rc;
385*44e33a5aSSean Rhodes 	unsigned long flags;
386*44e33a5aSSean Rhodes 
387*44e33a5aSSean Rhodes 	/* For the moment, only support buffers that exactly match in size */
388*44e33a5aSSean Rhodes 	if (*name_size != GSMI_BUF_SIZE)
389*44e33a5aSSean Rhodes 		return EFI_BAD_BUFFER_SIZE;
390*44e33a5aSSean Rhodes 
391*44e33a5aSSean Rhodes 	/* Let's make sure the thing is at least null-terminated */
392*44e33a5aSSean Rhodes 	if (ucs2_strnlen(name, GSMI_BUF_SIZE / 2) == GSMI_BUF_SIZE / 2)
393*44e33a5aSSean Rhodes 		return EFI_INVALID_PARAMETER;
394*44e33a5aSSean Rhodes 
395*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
396*44e33a5aSSean Rhodes 
397*44e33a5aSSean Rhodes 	/* guid */
398*44e33a5aSSean Rhodes 	memcpy(&param.guid, vendor, sizeof(param.guid));
399*44e33a5aSSean Rhodes 
400*44e33a5aSSean Rhodes 	/* variable name, already in UTF-16 */
401*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.name_buf->start, name, *name_size);
402*44e33a5aSSean Rhodes 
403*44e33a5aSSean Rhodes 	/* parameter buffer */
404*44e33a5aSSean Rhodes 	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
405*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
406*44e33a5aSSean Rhodes 
407*44e33a5aSSean Rhodes 	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NEXT_VAR);
408*44e33a5aSSean Rhodes 	if (rc < 0) {
409*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: Get Next Variable Name failed\n");
410*44e33a5aSSean Rhodes 		ret = EFI_LOAD_ERROR;
411*44e33a5aSSean Rhodes 	} else if (rc == 1) {
412*44e33a5aSSean Rhodes 		/* variable not found -- end of list */
413*44e33a5aSSean Rhodes 		ret = EFI_NOT_FOUND;
414*44e33a5aSSean Rhodes 	} else {
415*44e33a5aSSean Rhodes 		/* copy variable data back to return buffer */
416*44e33a5aSSean Rhodes 		memcpy(&param, gsmi_dev.param_buf->start, sizeof(param));
417*44e33a5aSSean Rhodes 
418*44e33a5aSSean Rhodes 		/* Copy the name back */
419*44e33a5aSSean Rhodes 		memcpy(name, gsmi_dev.name_buf->start, GSMI_BUF_SIZE);
420*44e33a5aSSean Rhodes 		*name_size = ucs2_strnlen(name, GSMI_BUF_SIZE / 2) * 2;
421*44e33a5aSSean Rhodes 
422*44e33a5aSSean Rhodes 		/* copy guid to return buffer */
423*44e33a5aSSean Rhodes 		memcpy(vendor, &param.guid, sizeof(param.guid));
424*44e33a5aSSean Rhodes 		ret = EFI_SUCCESS;
425*44e33a5aSSean Rhodes 	}
426*44e33a5aSSean Rhodes 
427*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
428*44e33a5aSSean Rhodes 
429*44e33a5aSSean Rhodes 	return ret;
430*44e33a5aSSean Rhodes }
431*44e33a5aSSean Rhodes 
gsmi_set_variable(efi_char16_t * name,efi_guid_t * vendor,u32 attr,unsigned long data_size,void * data)432*44e33a5aSSean Rhodes static efi_status_t gsmi_set_variable(efi_char16_t *name,
433*44e33a5aSSean Rhodes 				      efi_guid_t *vendor,
434*44e33a5aSSean Rhodes 				      u32 attr,
435*44e33a5aSSean Rhodes 				      unsigned long data_size,
436*44e33a5aSSean Rhodes 				      void *data)
437*44e33a5aSSean Rhodes {
438*44e33a5aSSean Rhodes 	struct gsmi_nvram_var_param param = {
439*44e33a5aSSean Rhodes 		.name_ptr = gsmi_dev.name_buf->address,
440*44e33a5aSSean Rhodes 		.data_ptr = gsmi_dev.data_buf->address,
441*44e33a5aSSean Rhodes 		.data_len = (u32)data_size,
442*44e33a5aSSean Rhodes 		.attributes = EFI_VARIABLE_NON_VOLATILE |
443*44e33a5aSSean Rhodes 			      EFI_VARIABLE_BOOTSERVICE_ACCESS |
444*44e33a5aSSean Rhodes 			      EFI_VARIABLE_RUNTIME_ACCESS,
445*44e33a5aSSean Rhodes 	};
446*44e33a5aSSean Rhodes 	size_t name_len = ucs2_strnlen(name, GSMI_BUF_SIZE / 2);
447*44e33a5aSSean Rhodes 	efi_status_t ret = EFI_SUCCESS;
448*44e33a5aSSean Rhodes 	int rc;
449*44e33a5aSSean Rhodes 	unsigned long flags;
450*44e33a5aSSean Rhodes 
451*44e33a5aSSean Rhodes 	if (name_len >= GSMI_BUF_SIZE / 2)
452*44e33a5aSSean Rhodes 		return EFI_BAD_BUFFER_SIZE;
453*44e33a5aSSean Rhodes 
454*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
455*44e33a5aSSean Rhodes 
456*44e33a5aSSean Rhodes 	/* guid */
457*44e33a5aSSean Rhodes 	memcpy(&param.guid, vendor, sizeof(param.guid));
458*44e33a5aSSean Rhodes 
459*44e33a5aSSean Rhodes 	/* variable name, already in UTF-16 */
460*44e33a5aSSean Rhodes 	memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
461*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
462*44e33a5aSSean Rhodes 
463*44e33a5aSSean Rhodes 	/* data pointer */
464*44e33a5aSSean Rhodes 	memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
465*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.data_buf->start, data, data_size);
466*44e33a5aSSean Rhodes 
467*44e33a5aSSean Rhodes 	/* parameter buffer */
468*44e33a5aSSean Rhodes 	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
469*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
470*44e33a5aSSean Rhodes 
471*44e33a5aSSean Rhodes 	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_NVRAM_VAR);
472*44e33a5aSSean Rhodes 	if (rc < 0) {
473*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: Set Variable failed\n");
474*44e33a5aSSean Rhodes 		ret = EFI_INVALID_PARAMETER;
475*44e33a5aSSean Rhodes 	}
476*44e33a5aSSean Rhodes 
477*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
478*44e33a5aSSean Rhodes 
479*44e33a5aSSean Rhodes 	return ret;
480*44e33a5aSSean Rhodes }
481*44e33a5aSSean Rhodes 
482*44e33a5aSSean Rhodes static const struct efivar_operations efivar_ops = {
483*44e33a5aSSean Rhodes 	.get_variable = gsmi_get_variable,
484*44e33a5aSSean Rhodes 	.set_variable = gsmi_set_variable,
485*44e33a5aSSean Rhodes 	.get_next_variable = gsmi_get_next_variable,
486*44e33a5aSSean Rhodes };
487*44e33a5aSSean Rhodes 
488*44e33a5aSSean Rhodes #endif /* CONFIG_EFI */
489*44e33a5aSSean Rhodes 
eventlog_write(struct file * filp,struct kobject * kobj,const struct bin_attribute * bin_attr,char * buf,loff_t pos,size_t count)490*44e33a5aSSean Rhodes static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
491*44e33a5aSSean Rhodes 			       const struct bin_attribute *bin_attr,
492*44e33a5aSSean Rhodes 			       char *buf, loff_t pos, size_t count)
493*44e33a5aSSean Rhodes {
494*44e33a5aSSean Rhodes 	struct gsmi_set_eventlog_param param = {
495*44e33a5aSSean Rhodes 		.data_ptr = gsmi_dev.data_buf->address,
496*44e33a5aSSean Rhodes 	};
497*44e33a5aSSean Rhodes 	int rc = 0;
498*44e33a5aSSean Rhodes 	unsigned long flags;
499*44e33a5aSSean Rhodes 
500*44e33a5aSSean Rhodes 	/* Pull the type out */
501*44e33a5aSSean Rhodes 	if (count < sizeof(u32))
502*44e33a5aSSean Rhodes 		return -EINVAL;
503*44e33a5aSSean Rhodes 	param.type = *(u32 *)buf;
504*44e33a5aSSean Rhodes 	buf += sizeof(u32);
505*44e33a5aSSean Rhodes 
506*44e33a5aSSean Rhodes 	/* The remaining buffer is the data payload */
507*44e33a5aSSean Rhodes 	if ((count - sizeof(u32)) > gsmi_dev.data_buf->length)
508*44e33a5aSSean Rhodes 		return -EINVAL;
509*44e33a5aSSean Rhodes 	param.data_len = count - sizeof(u32);
510*44e33a5aSSean Rhodes 
511*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
512*44e33a5aSSean Rhodes 
513*44e33a5aSSean Rhodes 	/* data pointer */
514*44e33a5aSSean Rhodes 	memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
515*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.data_buf->start, buf, param.data_len);
516*44e33a5aSSean Rhodes 
517*44e33a5aSSean Rhodes 	/* parameter buffer */
518*44e33a5aSSean Rhodes 	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
519*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
520*44e33a5aSSean Rhodes 
521*44e33a5aSSean Rhodes 	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
522*44e33a5aSSean Rhodes 	if (rc < 0)
523*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: Set Event Log failed\n");
524*44e33a5aSSean Rhodes 
525*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
526*44e33a5aSSean Rhodes 
527*44e33a5aSSean Rhodes 	return (rc == 0) ? count : rc;
528*44e33a5aSSean Rhodes 
529*44e33a5aSSean Rhodes }
530*44e33a5aSSean Rhodes 
531*44e33a5aSSean Rhodes static const struct bin_attribute eventlog_bin_attr = {
532*44e33a5aSSean Rhodes 	.attr = {.name = "append_to_eventlog", .mode = 0200},
533*44e33a5aSSean Rhodes 	.write = eventlog_write,
534*44e33a5aSSean Rhodes };
535*44e33a5aSSean Rhodes 
gsmi_clear_eventlog_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)536*44e33a5aSSean Rhodes static ssize_t gsmi_clear_eventlog_store(struct kobject *kobj,
537*44e33a5aSSean Rhodes 					 struct kobj_attribute *attr,
538*44e33a5aSSean Rhodes 					 const char *buf, size_t count)
539*44e33a5aSSean Rhodes {
540*44e33a5aSSean Rhodes 	int rc;
541*44e33a5aSSean Rhodes 	unsigned long flags;
542*44e33a5aSSean Rhodes 	unsigned long val;
543*44e33a5aSSean Rhodes 	struct {
544*44e33a5aSSean Rhodes 		u32 percentage;
545*44e33a5aSSean Rhodes 		u32 data_type;
546*44e33a5aSSean Rhodes 	} param;
547*44e33a5aSSean Rhodes 
548*44e33a5aSSean Rhodes 	rc = kstrtoul(buf, 0, &val);
549*44e33a5aSSean Rhodes 	if (rc)
550*44e33a5aSSean Rhodes 		return rc;
551*44e33a5aSSean Rhodes 
552*44e33a5aSSean Rhodes 	/*
553*44e33a5aSSean Rhodes 	 * Value entered is a percentage, 0 through 100, anything else
554*44e33a5aSSean Rhodes 	 * is invalid.
555*44e33a5aSSean Rhodes 	 */
556*44e33a5aSSean Rhodes 	if (val > 100)
557*44e33a5aSSean Rhodes 		return -EINVAL;
558*44e33a5aSSean Rhodes 
559*44e33a5aSSean Rhodes 	/* data_type here selects the smbios event log. */
560*44e33a5aSSean Rhodes 	param.percentage = val;
561*44e33a5aSSean Rhodes 	param.data_type = 0;
562*44e33a5aSSean Rhodes 
563*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
564*44e33a5aSSean Rhodes 
565*44e33a5aSSean Rhodes 	/* parameter buffer */
566*44e33a5aSSean Rhodes 	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
567*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
568*44e33a5aSSean Rhodes 
569*44e33a5aSSean Rhodes 	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_EVENT_LOG);
570*44e33a5aSSean Rhodes 
571*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
572*44e33a5aSSean Rhodes 
573*44e33a5aSSean Rhodes 	if (rc)
574*44e33a5aSSean Rhodes 		return rc;
575*44e33a5aSSean Rhodes 	return count;
576*44e33a5aSSean Rhodes }
577*44e33a5aSSean Rhodes 
578*44e33a5aSSean Rhodes static struct kobj_attribute gsmi_clear_eventlog_attr = {
579*44e33a5aSSean Rhodes 	.attr = {.name = "clear_eventlog", .mode = 0200},
580*44e33a5aSSean Rhodes 	.store = gsmi_clear_eventlog_store,
581*44e33a5aSSean Rhodes };
582*44e33a5aSSean Rhodes 
gsmi_clear_config_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)583*44e33a5aSSean Rhodes static ssize_t gsmi_clear_config_store(struct kobject *kobj,
584*44e33a5aSSean Rhodes 				       struct kobj_attribute *attr,
585*44e33a5aSSean Rhodes 				       const char *buf, size_t count)
586*44e33a5aSSean Rhodes {
587*44e33a5aSSean Rhodes 	int rc;
588*44e33a5aSSean Rhodes 	unsigned long flags;
589*44e33a5aSSean Rhodes 
590*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
591*44e33a5aSSean Rhodes 
592*44e33a5aSSean Rhodes 	/* clear parameter buffer */
593*44e33a5aSSean Rhodes 	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
594*44e33a5aSSean Rhodes 
595*44e33a5aSSean Rhodes 	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_CONFIG);
596*44e33a5aSSean Rhodes 
597*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
598*44e33a5aSSean Rhodes 
599*44e33a5aSSean Rhodes 	if (rc)
600*44e33a5aSSean Rhodes 		return rc;
601*44e33a5aSSean Rhodes 	return count;
602*44e33a5aSSean Rhodes }
603*44e33a5aSSean Rhodes 
604*44e33a5aSSean Rhodes static struct kobj_attribute gsmi_clear_config_attr = {
605*44e33a5aSSean Rhodes 	.attr = {.name = "clear_config", .mode = 0200},
606*44e33a5aSSean Rhodes 	.store = gsmi_clear_config_store,
607*44e33a5aSSean Rhodes };
608*44e33a5aSSean Rhodes 
609*44e33a5aSSean Rhodes static const struct attribute *gsmi_attrs[] = {
610*44e33a5aSSean Rhodes 	&gsmi_clear_config_attr.attr,
611*44e33a5aSSean Rhodes 	&gsmi_clear_eventlog_attr.attr,
612*44e33a5aSSean Rhodes 	NULL,
613*44e33a5aSSean Rhodes };
614*44e33a5aSSean Rhodes 
gsmi_shutdown_reason(int reason)615*44e33a5aSSean Rhodes static int gsmi_shutdown_reason(int reason)
616*44e33a5aSSean Rhodes {
617*44e33a5aSSean Rhodes 	struct gsmi_log_entry_type_1 entry = {
618*44e33a5aSSean Rhodes 		.type     = GSMI_LOG_ENTRY_TYPE_KERNEL,
619*44e33a5aSSean Rhodes 		.instance = reason,
620*44e33a5aSSean Rhodes 	};
621*44e33a5aSSean Rhodes 	struct gsmi_set_eventlog_param param = {
622*44e33a5aSSean Rhodes 		.data_len = sizeof(entry),
623*44e33a5aSSean Rhodes 		.type     = 1,
624*44e33a5aSSean Rhodes 	};
625*44e33a5aSSean Rhodes 	static int saved_reason;
626*44e33a5aSSean Rhodes 	int rc = 0;
627*44e33a5aSSean Rhodes 	unsigned long flags;
628*44e33a5aSSean Rhodes 
629*44e33a5aSSean Rhodes 	/* avoid duplicate entries in the log */
630*44e33a5aSSean Rhodes 	if (saved_reason & (1 << reason))
631*44e33a5aSSean Rhodes 		return 0;
632*44e33a5aSSean Rhodes 
633*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
634*44e33a5aSSean Rhodes 
635*44e33a5aSSean Rhodes 	saved_reason |= (1 << reason);
636*44e33a5aSSean Rhodes 
637*44e33a5aSSean Rhodes 	/* data pointer */
638*44e33a5aSSean Rhodes 	memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
639*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.data_buf->start, &entry, sizeof(entry));
640*44e33a5aSSean Rhodes 
641*44e33a5aSSean Rhodes 	/* parameter buffer */
642*44e33a5aSSean Rhodes 	param.data_ptr = gsmi_dev.data_buf->address;
643*44e33a5aSSean Rhodes 	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
644*44e33a5aSSean Rhodes 	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
645*44e33a5aSSean Rhodes 
646*44e33a5aSSean Rhodes 	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
647*44e33a5aSSean Rhodes 
648*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
649*44e33a5aSSean Rhodes 
650*44e33a5aSSean Rhodes 	if (rc < 0)
651*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: Log Shutdown Reason failed\n");
652*44e33a5aSSean Rhodes 	else
653*44e33a5aSSean Rhodes 		printk(KERN_EMERG "gsmi: Log Shutdown Reason 0x%02x\n",
654*44e33a5aSSean Rhodes 		       reason);
655*44e33a5aSSean Rhodes 
656*44e33a5aSSean Rhodes 	return rc;
657*44e33a5aSSean Rhodes }
658*44e33a5aSSean Rhodes 
gsmi_reboot_callback(struct notifier_block * nb,unsigned long reason,void * arg)659*44e33a5aSSean Rhodes static int gsmi_reboot_callback(struct notifier_block *nb,
660*44e33a5aSSean Rhodes 				unsigned long reason, void *arg)
661*44e33a5aSSean Rhodes {
662*44e33a5aSSean Rhodes 	gsmi_shutdown_reason(GSMI_SHUTDOWN_CLEAN);
663*44e33a5aSSean Rhodes 	return NOTIFY_DONE;
664*44e33a5aSSean Rhodes }
665*44e33a5aSSean Rhodes 
666*44e33a5aSSean Rhodes static struct notifier_block gsmi_reboot_notifier = {
667*44e33a5aSSean Rhodes 	.notifier_call = gsmi_reboot_callback
668*44e33a5aSSean Rhodes };
669*44e33a5aSSean Rhodes 
gsmi_die_callback(struct notifier_block * nb,unsigned long reason,void * arg)670*44e33a5aSSean Rhodes static int gsmi_die_callback(struct notifier_block *nb,
671*44e33a5aSSean Rhodes 			     unsigned long reason, void *arg)
672*44e33a5aSSean Rhodes {
673*44e33a5aSSean Rhodes 	if (reason == DIE_OOPS)
674*44e33a5aSSean Rhodes 		gsmi_shutdown_reason(GSMI_SHUTDOWN_OOPS);
675*44e33a5aSSean Rhodes 	return NOTIFY_DONE;
676*44e33a5aSSean Rhodes }
677*44e33a5aSSean Rhodes 
678*44e33a5aSSean Rhodes static struct notifier_block gsmi_die_notifier = {
679*44e33a5aSSean Rhodes 	.notifier_call = gsmi_die_callback
680*44e33a5aSSean Rhodes };
681*44e33a5aSSean Rhodes 
gsmi_panic_callback(struct notifier_block * nb,unsigned long reason,void * arg)682*44e33a5aSSean Rhodes static int gsmi_panic_callback(struct notifier_block *nb,
683*44e33a5aSSean Rhodes 			       unsigned long reason, void *arg)
684*44e33a5aSSean Rhodes {
685*44e33a5aSSean Rhodes 
686*44e33a5aSSean Rhodes 	/*
687*44e33a5aSSean Rhodes 	 * Panic callbacks are executed with all other CPUs stopped,
688*44e33a5aSSean Rhodes 	 * so we must not attempt to spin waiting for gsmi_dev.lock
689*44e33a5aSSean Rhodes 	 * to be released.
690*44e33a5aSSean Rhodes 	 */
691*44e33a5aSSean Rhodes 	if (spin_is_locked(&gsmi_dev.lock))
692*44e33a5aSSean Rhodes 		return NOTIFY_DONE;
693*44e33a5aSSean Rhodes 
694*44e33a5aSSean Rhodes 	gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
695*44e33a5aSSean Rhodes 	return NOTIFY_DONE;
696*44e33a5aSSean Rhodes }
697*44e33a5aSSean Rhodes 
698*44e33a5aSSean Rhodes static struct notifier_block gsmi_panic_notifier = {
699*44e33a5aSSean Rhodes 	.notifier_call = gsmi_panic_callback,
700*44e33a5aSSean Rhodes };
701*44e33a5aSSean Rhodes 
702*44e33a5aSSean Rhodes /*
703*44e33a5aSSean Rhodes  * This hash function was blatantly copied from include/linux/hash.h.
704*44e33a5aSSean Rhodes  * It is used by this driver to obfuscate a board name that requires a
705*44e33a5aSSean Rhodes  * quirk within this driver.
706*44e33a5aSSean Rhodes  *
707*44e33a5aSSean Rhodes  * Please do not remove this copy of the function as any changes to the
708*44e33a5aSSean Rhodes  * global utility hash_64() function would break this driver's ability
709*44e33a5aSSean Rhodes  * to identify a board and provide the appropriate quirk -- mikew@google.com
710*44e33a5aSSean Rhodes  */
local_hash_64(u64 val,unsigned bits)711*44e33a5aSSean Rhodes static u64 __init local_hash_64(u64 val, unsigned bits)
712*44e33a5aSSean Rhodes {
713*44e33a5aSSean Rhodes 	u64 hash = val;
714*44e33a5aSSean Rhodes 
715*44e33a5aSSean Rhodes 	/*  Sigh, gcc can't optimise this alone like it does for 32 bits. */
716*44e33a5aSSean Rhodes 	u64 n = hash;
717*44e33a5aSSean Rhodes 	n <<= 18;
718*44e33a5aSSean Rhodes 	hash -= n;
719*44e33a5aSSean Rhodes 	n <<= 33;
720*44e33a5aSSean Rhodes 	hash -= n;
721*44e33a5aSSean Rhodes 	n <<= 3;
722*44e33a5aSSean Rhodes 	hash += n;
723*44e33a5aSSean Rhodes 	n <<= 3;
724*44e33a5aSSean Rhodes 	hash -= n;
725*44e33a5aSSean Rhodes 	n <<= 4;
726*44e33a5aSSean Rhodes 	hash += n;
727*44e33a5aSSean Rhodes 	n <<= 2;
728*44e33a5aSSean Rhodes 	hash += n;
729*44e33a5aSSean Rhodes 
730*44e33a5aSSean Rhodes 	/* High bits are more random, so use them. */
731*44e33a5aSSean Rhodes 	return hash >> (64 - bits);
732*44e33a5aSSean Rhodes }
733*44e33a5aSSean Rhodes 
hash_oem_table_id(char s[8])734*44e33a5aSSean Rhodes static u32 __init hash_oem_table_id(char s[8])
735*44e33a5aSSean Rhodes {
736*44e33a5aSSean Rhodes 	u64 input;
737*44e33a5aSSean Rhodes 	memcpy(&input, s, 8);
738*44e33a5aSSean Rhodes 	return local_hash_64(input, 32);
739*44e33a5aSSean Rhodes }
740*44e33a5aSSean Rhodes 
741*44e33a5aSSean Rhodes static const struct dmi_system_id gsmi_dmi_table[] __initconst = {
742*44e33a5aSSean Rhodes 	{
743*44e33a5aSSean Rhodes 		.ident = "Google Board",
744*44e33a5aSSean Rhodes 		.matches = {
745*44e33a5aSSean Rhodes 			DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
746*44e33a5aSSean Rhodes 		},
747*44e33a5aSSean Rhodes 	},
748*44e33a5aSSean Rhodes 	{
749*44e33a5aSSean Rhodes 		.ident = "Coreboot Firmware",
750*44e33a5aSSean Rhodes 		.matches = {
751*44e33a5aSSean Rhodes 			DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
752*44e33a5aSSean Rhodes 		},
753*44e33a5aSSean Rhodes 	},
754*44e33a5aSSean Rhodes 	{}
755*44e33a5aSSean Rhodes };
756*44e33a5aSSean Rhodes MODULE_DEVICE_TABLE(dmi, gsmi_dmi_table);
757*44e33a5aSSean Rhodes 
gsmi_system_valid(void)758*44e33a5aSSean Rhodes static __init int gsmi_system_valid(void)
759*44e33a5aSSean Rhodes {
760*44e33a5aSSean Rhodes 	u32 hash;
761*44e33a5aSSean Rhodes 	u16 cmd, result;
762*44e33a5aSSean Rhodes 
763*44e33a5aSSean Rhodes 	if (!dmi_check_system(gsmi_dmi_table))
764*44e33a5aSSean Rhodes 		return -ENODEV;
765*44e33a5aSSean Rhodes 
766*44e33a5aSSean Rhodes 	/*
767*44e33a5aSSean Rhodes 	 * Only newer firmware supports the gsmi interface.  All older
768*44e33a5aSSean Rhodes 	 * firmware that didn't support this interface used to plug the
769*44e33a5aSSean Rhodes 	 * table name in the first four bytes of the oem_table_id field.
770*44e33a5aSSean Rhodes 	 * Newer firmware doesn't do that though, so use that as the
771*44e33a5aSSean Rhodes 	 * discriminant factor.  We have to do this in order to
772*44e33a5aSSean Rhodes 	 * whitewash our board names out of the public driver.
773*44e33a5aSSean Rhodes 	 */
774*44e33a5aSSean Rhodes 	if (!strncmp(acpi_gbl_FADT.header.oem_table_id, "FACP", 4)) {
775*44e33a5aSSean Rhodes 		printk(KERN_INFO "gsmi: Board is too old\n");
776*44e33a5aSSean Rhodes 		return -ENODEV;
777*44e33a5aSSean Rhodes 	}
778*44e33a5aSSean Rhodes 
779*44e33a5aSSean Rhodes 	/* Disable on board with 1.0 BIOS due to Google bug 2602657 */
780*44e33a5aSSean Rhodes 	hash = hash_oem_table_id(acpi_gbl_FADT.header.oem_table_id);
781*44e33a5aSSean Rhodes 	if (hash == QUIRKY_BOARD_HASH) {
782*44e33a5aSSean Rhodes 		const char *bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
783*44e33a5aSSean Rhodes 		if (strncmp(bios_ver, "1.0", 3) == 0) {
784*44e33a5aSSean Rhodes 			pr_info("gsmi: disabled on this board's BIOS %s\n",
785*44e33a5aSSean Rhodes 				bios_ver);
786*44e33a5aSSean Rhodes 			return -ENODEV;
787*44e33a5aSSean Rhodes 		}
788*44e33a5aSSean Rhodes 	}
789*44e33a5aSSean Rhodes 
790*44e33a5aSSean Rhodes 	/* check for valid SMI command port in ACPI FADT */
791*44e33a5aSSean Rhodes 	if (acpi_gbl_FADT.smi_command == 0) {
792*44e33a5aSSean Rhodes 		pr_info("gsmi: missing smi_command\n");
793*44e33a5aSSean Rhodes 		return -ENODEV;
794*44e33a5aSSean Rhodes 	}
795*44e33a5aSSean Rhodes 
796*44e33a5aSSean Rhodes 	/* Test the smihandler with a bogus command. If it leaves the
797*44e33a5aSSean Rhodes 	 * calling argument in %ax untouched, there is no handler for
798*44e33a5aSSean Rhodes 	 * GSMI commands.
799*44e33a5aSSean Rhodes 	 */
800*44e33a5aSSean Rhodes 	cmd = GSMI_CALLBACK | GSMI_CMD_RESERVED << 8;
801*44e33a5aSSean Rhodes 	asm volatile (
802*44e33a5aSSean Rhodes 		"outb %%al, %%dx\n\t"
803*44e33a5aSSean Rhodes 		: "=a" (result)
804*44e33a5aSSean Rhodes 		: "0" (cmd),
805*44e33a5aSSean Rhodes 		  "d" (acpi_gbl_FADT.smi_command)
806*44e33a5aSSean Rhodes 		: "memory", "cc"
807*44e33a5aSSean Rhodes 		);
808*44e33a5aSSean Rhodes 	if (cmd == result) {
809*44e33a5aSSean Rhodes 		pr_info("gsmi: no gsmi handler in firmware\n");
810*44e33a5aSSean Rhodes 		return -ENODEV;
811*44e33a5aSSean Rhodes 	}
812*44e33a5aSSean Rhodes 
813*44e33a5aSSean Rhodes 	/* Found */
814*44e33a5aSSean Rhodes 	return 0;
815*44e33a5aSSean Rhodes }
816*44e33a5aSSean Rhodes 
817*44e33a5aSSean Rhodes static struct kobject *gsmi_kobj;
818*44e33a5aSSean Rhodes 
819*44e33a5aSSean Rhodes static const struct platform_device_info gsmi_dev_info = {
820*44e33a5aSSean Rhodes 	.name		= "gsmi",
821*44e33a5aSSean Rhodes 	.id		= -1,
822*44e33a5aSSean Rhodes 	/* SMI callbacks require 32bit addresses */
823*44e33a5aSSean Rhodes 	.dma_mask	= DMA_BIT_MASK(32),
824*44e33a5aSSean Rhodes };
825*44e33a5aSSean Rhodes 
826*44e33a5aSSean Rhodes #ifdef CONFIG_PM
gsmi_log_s0ix_info(u8 cmd)827*44e33a5aSSean Rhodes static void gsmi_log_s0ix_info(u8 cmd)
828*44e33a5aSSean Rhodes {
829*44e33a5aSSean Rhodes 	unsigned long flags;
830*44e33a5aSSean Rhodes 
831*44e33a5aSSean Rhodes 	/*
832*44e33a5aSSean Rhodes 	 * If platform has not enabled S0ix logging, then no action is
833*44e33a5aSSean Rhodes 	 * necessary.
834*44e33a5aSSean Rhodes 	 */
835*44e33a5aSSean Rhodes 	if (!s0ix_logging_enable)
836*44e33a5aSSean Rhodes 		return;
837*44e33a5aSSean Rhodes 
838*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
839*44e33a5aSSean Rhodes 
840*44e33a5aSSean Rhodes 	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
841*44e33a5aSSean Rhodes 
842*44e33a5aSSean Rhodes 	gsmi_exec(GSMI_CALLBACK, cmd);
843*44e33a5aSSean Rhodes 
844*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
845*44e33a5aSSean Rhodes }
846*44e33a5aSSean Rhodes 
gsmi_log_s0ix_suspend(struct device * dev)847*44e33a5aSSean Rhodes static int gsmi_log_s0ix_suspend(struct device *dev)
848*44e33a5aSSean Rhodes {
849*44e33a5aSSean Rhodes 	/*
850*44e33a5aSSean Rhodes 	 * If system is not suspending via firmware using the standard ACPI Sx
851*44e33a5aSSean Rhodes 	 * types, then make a GSMI call to log the suspend info.
852*44e33a5aSSean Rhodes 	 */
853*44e33a5aSSean Rhodes 	if (!pm_suspend_via_firmware())
854*44e33a5aSSean Rhodes 		gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_SUSPEND);
855*44e33a5aSSean Rhodes 
856*44e33a5aSSean Rhodes 	/*
857*44e33a5aSSean Rhodes 	 * Always return success, since we do not want suspend
858*44e33a5aSSean Rhodes 	 * to fail just because of logging failure.
859*44e33a5aSSean Rhodes 	 */
860*44e33a5aSSean Rhodes 	return 0;
861*44e33a5aSSean Rhodes }
862*44e33a5aSSean Rhodes 
gsmi_log_s0ix_resume(struct device * dev)863*44e33a5aSSean Rhodes static int gsmi_log_s0ix_resume(struct device *dev)
864*44e33a5aSSean Rhodes {
865*44e33a5aSSean Rhodes 	/*
866*44e33a5aSSean Rhodes 	 * If system did not resume via firmware, then make a GSMI call to log
867*44e33a5aSSean Rhodes 	 * the resume info and wake source.
868*44e33a5aSSean Rhodes 	 */
869*44e33a5aSSean Rhodes 	if (!pm_resume_via_firmware())
870*44e33a5aSSean Rhodes 		gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_RESUME);
871*44e33a5aSSean Rhodes 
872*44e33a5aSSean Rhodes 	/*
873*44e33a5aSSean Rhodes 	 * Always return success, since we do not want resume
874*44e33a5aSSean Rhodes 	 * to fail just because of logging failure.
875*44e33a5aSSean Rhodes 	 */
876*44e33a5aSSean Rhodes 	return 0;
877*44e33a5aSSean Rhodes }
878*44e33a5aSSean Rhodes 
879*44e33a5aSSean Rhodes static const struct dev_pm_ops gsmi_pm_ops = {
880*44e33a5aSSean Rhodes 	.suspend_noirq = gsmi_log_s0ix_suspend,
881*44e33a5aSSean Rhodes 	.resume_noirq = gsmi_log_s0ix_resume,
882*44e33a5aSSean Rhodes };
883*44e33a5aSSean Rhodes 
gsmi_platform_driver_probe(struct platform_device * dev)884*44e33a5aSSean Rhodes static int gsmi_platform_driver_probe(struct platform_device *dev)
885*44e33a5aSSean Rhodes {
886*44e33a5aSSean Rhodes 	return 0;
887*44e33a5aSSean Rhodes }
888*44e33a5aSSean Rhodes 
889*44e33a5aSSean Rhodes static struct platform_driver gsmi_driver_info = {
890*44e33a5aSSean Rhodes 	.driver = {
891*44e33a5aSSean Rhodes 		.name = "gsmi",
892*44e33a5aSSean Rhodes 		.pm = &gsmi_pm_ops,
893*44e33a5aSSean Rhodes 	},
894*44e33a5aSSean Rhodes 	.probe = gsmi_platform_driver_probe,
895*44e33a5aSSean Rhodes };
896*44e33a5aSSean Rhodes #endif
897*44e33a5aSSean Rhodes 
gsmi_init(void)898*44e33a5aSSean Rhodes static __init int gsmi_init(void)
899*44e33a5aSSean Rhodes {
900*44e33a5aSSean Rhodes 	unsigned long flags;
901*44e33a5aSSean Rhodes 	int ret;
902*44e33a5aSSean Rhodes 
903*44e33a5aSSean Rhodes 	ret = gsmi_system_valid();
904*44e33a5aSSean Rhodes 	if (ret)
905*44e33a5aSSean Rhodes 		return ret;
906*44e33a5aSSean Rhodes 
907*44e33a5aSSean Rhodes 	gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
908*44e33a5aSSean Rhodes 
909*44e33a5aSSean Rhodes #ifdef CONFIG_PM
910*44e33a5aSSean Rhodes 	ret = platform_driver_register(&gsmi_driver_info);
911*44e33a5aSSean Rhodes 	if (unlikely(ret)) {
912*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: unable to register platform driver\n");
913*44e33a5aSSean Rhodes 		return ret;
914*44e33a5aSSean Rhodes 	}
915*44e33a5aSSean Rhodes #endif
916*44e33a5aSSean Rhodes 
917*44e33a5aSSean Rhodes 	/* register device */
918*44e33a5aSSean Rhodes 	gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
919*44e33a5aSSean Rhodes 	if (IS_ERR(gsmi_dev.pdev)) {
920*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: unable to register platform device\n");
921*44e33a5aSSean Rhodes 		ret = PTR_ERR(gsmi_dev.pdev);
922*44e33a5aSSean Rhodes 		goto out_unregister;
923*44e33a5aSSean Rhodes 	}
924*44e33a5aSSean Rhodes 
925*44e33a5aSSean Rhodes 	/* SMI access needs to be serialized */
926*44e33a5aSSean Rhodes 	spin_lock_init(&gsmi_dev.lock);
927*44e33a5aSSean Rhodes 
928*44e33a5aSSean Rhodes 	ret = -ENOMEM;
929*44e33a5aSSean Rhodes 
930*44e33a5aSSean Rhodes 	/*
931*44e33a5aSSean Rhodes 	 * SLAB cache is created using SLAB_CACHE_DMA32 to ensure that the
932*44e33a5aSSean Rhodes 	 * allocations for gsmi_buf come from the DMA32 memory zone. These
933*44e33a5aSSean Rhodes 	 * buffers have nothing to do with DMA. They are required for
934*44e33a5aSSean Rhodes 	 * communication with firmware executing in SMI mode which can only
935*44e33a5aSSean Rhodes 	 * access the bottom 4GiB of physical memory. Since DMA32 memory zone
936*44e33a5aSSean Rhodes 	 * guarantees allocation under the 4GiB boundary, this driver creates
937*44e33a5aSSean Rhodes 	 * a SLAB cache with SLAB_CACHE_DMA32 flag.
938*44e33a5aSSean Rhodes 	 */
939*44e33a5aSSean Rhodes 	gsmi_dev.mem_pool = kmem_cache_create("gsmi", GSMI_BUF_SIZE,
940*44e33a5aSSean Rhodes 					      GSMI_BUF_ALIGN,
941*44e33a5aSSean Rhodes 					      SLAB_CACHE_DMA32, NULL);
942*44e33a5aSSean Rhodes 	if (!gsmi_dev.mem_pool)
943*44e33a5aSSean Rhodes 		goto out_err;
944*44e33a5aSSean Rhodes 
945*44e33a5aSSean Rhodes 	/*
946*44e33a5aSSean Rhodes 	 * pre-allocate buffers because sometimes we are called when
947*44e33a5aSSean Rhodes 	 * this is not feasible: oops, panic, die, mce, etc
948*44e33a5aSSean Rhodes 	 */
949*44e33a5aSSean Rhodes 	gsmi_dev.name_buf = gsmi_buf_alloc();
950*44e33a5aSSean Rhodes 	if (!gsmi_dev.name_buf) {
951*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
952*44e33a5aSSean Rhodes 		goto out_err;
953*44e33a5aSSean Rhodes 	}
954*44e33a5aSSean Rhodes 
955*44e33a5aSSean Rhodes 	gsmi_dev.data_buf = gsmi_buf_alloc();
956*44e33a5aSSean Rhodes 	if (!gsmi_dev.data_buf) {
957*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: failed to allocate data buffer\n");
958*44e33a5aSSean Rhodes 		goto out_err;
959*44e33a5aSSean Rhodes 	}
960*44e33a5aSSean Rhodes 
961*44e33a5aSSean Rhodes 	gsmi_dev.param_buf = gsmi_buf_alloc();
962*44e33a5aSSean Rhodes 	if (!gsmi_dev.param_buf) {
963*44e33a5aSSean Rhodes 		printk(KERN_ERR "gsmi: failed to allocate param buffer\n");
964*44e33a5aSSean Rhodes 		goto out_err;
965*44e33a5aSSean Rhodes 	}
966*44e33a5aSSean Rhodes 
967*44e33a5aSSean Rhodes 	/*
968*44e33a5aSSean Rhodes 	 * Determine type of handshake used to serialize the SMI
969*44e33a5aSSean Rhodes 	 * entry. See also gsmi_exec().
970*44e33a5aSSean Rhodes 	 *
971*44e33a5aSSean Rhodes 	 * There's a "behavior" present on some chipsets where writing the
972*44e33a5aSSean Rhodes 	 * SMI trigger register in the southbridge doesn't result in an
973*44e33a5aSSean Rhodes 	 * immediate SMI. Rather, the processor can execute "a few" more
974*44e33a5aSSean Rhodes 	 * instructions before the SMI takes effect. To ensure synchronous
975*44e33a5aSSean Rhodes 	 * behavior, implement a handshake between the kernel driver and the
976*44e33a5aSSean Rhodes 	 * firmware handler to spin until released. This ioctl determines
977*44e33a5aSSean Rhodes 	 * the type of handshake.
978*44e33a5aSSean Rhodes 	 *
979*44e33a5aSSean Rhodes 	 * NONE: The firmware handler does not implement any
980*44e33a5aSSean Rhodes 	 * handshake. Either it doesn't need to, or it's legacy firmware
981*44e33a5aSSean Rhodes 	 * that doesn't know it needs to and never will.
982*44e33a5aSSean Rhodes 	 *
983*44e33a5aSSean Rhodes 	 * CF: The firmware handler will clear the CF in the saved
984*44e33a5aSSean Rhodes 	 * state before returning. The driver may set the CF and test for
985*44e33a5aSSean Rhodes 	 * it to clear before proceeding.
986*44e33a5aSSean Rhodes 	 *
987*44e33a5aSSean Rhodes 	 * SPIN: The firmware handler does not implement any handshake
988*44e33a5aSSean Rhodes 	 * but the driver should spin for a hundred or so microseconds
989*44e33a5aSSean Rhodes 	 * to ensure the SMI has triggered.
990*44e33a5aSSean Rhodes 	 *
991*44e33a5aSSean Rhodes 	 * Finally, the handler will return -ENOSYS if
992*44e33a5aSSean Rhodes 	 * GSMI_CMD_HANDSHAKE_TYPE is unimplemented, which implies
993*44e33a5aSSean Rhodes 	 * HANDSHAKE_NONE.
994*44e33a5aSSean Rhodes 	 */
995*44e33a5aSSean Rhodes 	spin_lock_irqsave(&gsmi_dev.lock, flags);
996*44e33a5aSSean Rhodes 	gsmi_dev.handshake_type = GSMI_HANDSHAKE_SPIN;
997*44e33a5aSSean Rhodes 	gsmi_dev.handshake_type =
998*44e33a5aSSean Rhodes 	    gsmi_exec(GSMI_CALLBACK, GSMI_CMD_HANDSHAKE_TYPE);
999*44e33a5aSSean Rhodes 	if (gsmi_dev.handshake_type == -ENOSYS)
1000*44e33a5aSSean Rhodes 		gsmi_dev.handshake_type = GSMI_HANDSHAKE_NONE;
1001*44e33a5aSSean Rhodes 	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
1002*44e33a5aSSean Rhodes 
1003*44e33a5aSSean Rhodes 	/* Remove and clean up gsmi if the handshake could not complete. */
1004*44e33a5aSSean Rhodes 	if (gsmi_dev.handshake_type == -ENXIO) {
1005*44e33a5aSSean Rhodes 		printk(KERN_INFO "gsmi version " DRIVER_VERSION
1006*44e33a5aSSean Rhodes 		       " failed to load\n");
1007*44e33a5aSSean Rhodes 		ret = -ENODEV;
1008*44e33a5aSSean Rhodes 		goto out_err;
1009*44e33a5aSSean Rhodes 	}
1010*44e33a5aSSean Rhodes 
1011*44e33a5aSSean Rhodes 	/* Register in the firmware directory */
1012*44e33a5aSSean Rhodes 	ret = -ENOMEM;
1013*44e33a5aSSean Rhodes 	gsmi_kobj = kobject_create_and_add("gsmi", firmware_kobj);
1014*44e33a5aSSean Rhodes 	if (!gsmi_kobj) {
1015*44e33a5aSSean Rhodes 		printk(KERN_INFO "gsmi: Failed to create firmware kobj\n");
1016*44e33a5aSSean Rhodes 		goto out_err;
1017*44e33a5aSSean Rhodes 	}
1018*44e33a5aSSean Rhodes 
1019*44e33a5aSSean Rhodes 	/* Setup eventlog access */
1020*44e33a5aSSean Rhodes 	ret = sysfs_create_bin_file(gsmi_kobj, &eventlog_bin_attr);
1021*44e33a5aSSean Rhodes 	if (ret) {
1022*44e33a5aSSean Rhodes 		printk(KERN_INFO "gsmi: Failed to setup eventlog");
1023*44e33a5aSSean Rhodes 		goto out_err;
1024*44e33a5aSSean Rhodes 	}
1025*44e33a5aSSean Rhodes 
1026*44e33a5aSSean Rhodes 	/* Other attributes */
1027*44e33a5aSSean Rhodes 	ret = sysfs_create_files(gsmi_kobj, gsmi_attrs);
1028*44e33a5aSSean Rhodes 	if (ret) {
1029*44e33a5aSSean Rhodes 		printk(KERN_INFO "gsmi: Failed to add attrs");
1030*44e33a5aSSean Rhodes 		goto out_remove_bin_file;
1031*44e33a5aSSean Rhodes 	}
1032*44e33a5aSSean Rhodes 
1033*44e33a5aSSean Rhodes #ifdef CONFIG_EFI
1034*44e33a5aSSean Rhodes 	ret = efivars_register(&efivars, &efivar_ops);
1035*44e33a5aSSean Rhodes 	if (ret) {
1036*44e33a5aSSean Rhodes 		printk(KERN_INFO "gsmi: Failed to register efivars\n");
1037*44e33a5aSSean Rhodes 		sysfs_remove_files(gsmi_kobj, gsmi_attrs);
1038*44e33a5aSSean Rhodes 		goto out_remove_bin_file;
1039*44e33a5aSSean Rhodes 	}
1040*44e33a5aSSean Rhodes #endif
1041*44e33a5aSSean Rhodes 
1042*44e33a5aSSean Rhodes 	register_reboot_notifier(&gsmi_reboot_notifier);
1043*44e33a5aSSean Rhodes 	register_die_notifier(&gsmi_die_notifier);
1044*44e33a5aSSean Rhodes 	atomic_notifier_chain_register(&panic_notifier_list,
1045*44e33a5aSSean Rhodes 				       &gsmi_panic_notifier);
1046*44e33a5aSSean Rhodes 
1047*44e33a5aSSean Rhodes 	printk(KERN_INFO "gsmi version " DRIVER_VERSION " loaded\n");
1048*44e33a5aSSean Rhodes 
1049*44e33a5aSSean Rhodes 	return 0;
1050*44e33a5aSSean Rhodes 
1051*44e33a5aSSean Rhodes out_remove_bin_file:
1052*44e33a5aSSean Rhodes 	sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
1053*44e33a5aSSean Rhodes out_err:
1054*44e33a5aSSean Rhodes 	kobject_put(gsmi_kobj);
1055*44e33a5aSSean Rhodes 	gsmi_buf_free(gsmi_dev.param_buf);
1056*44e33a5aSSean Rhodes 	gsmi_buf_free(gsmi_dev.data_buf);
1057*44e33a5aSSean Rhodes 	gsmi_buf_free(gsmi_dev.name_buf);
1058*44e33a5aSSean Rhodes 	kmem_cache_destroy(gsmi_dev.mem_pool);
1059*44e33a5aSSean Rhodes 	platform_device_unregister(gsmi_dev.pdev);
1060*44e33a5aSSean Rhodes out_unregister:
1061*44e33a5aSSean Rhodes #ifdef CONFIG_PM
1062*44e33a5aSSean Rhodes 	platform_driver_unregister(&gsmi_driver_info);
1063*44e33a5aSSean Rhodes #endif
1064*44e33a5aSSean Rhodes 	pr_info("gsmi: failed to load: %d\n", ret);
1065*44e33a5aSSean Rhodes 	return ret;
1066*44e33a5aSSean Rhodes }
1067*44e33a5aSSean Rhodes 
gsmi_exit(void)1068*44e33a5aSSean Rhodes static void __exit gsmi_exit(void)
1069*44e33a5aSSean Rhodes {
1070*44e33a5aSSean Rhodes 	unregister_reboot_notifier(&gsmi_reboot_notifier);
1071*44e33a5aSSean Rhodes 	unregister_die_notifier(&gsmi_die_notifier);
1072*44e33a5aSSean Rhodes 	atomic_notifier_chain_unregister(&panic_notifier_list,
1073*44e33a5aSSean Rhodes 					 &gsmi_panic_notifier);
1074*44e33a5aSSean Rhodes #ifdef CONFIG_EFI
1075*44e33a5aSSean Rhodes 	efivars_unregister(&efivars);
1076*44e33a5aSSean Rhodes #endif
1077*44e33a5aSSean Rhodes 
1078*44e33a5aSSean Rhodes 	sysfs_remove_files(gsmi_kobj, gsmi_attrs);
1079*44e33a5aSSean Rhodes 	sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
1080*44e33a5aSSean Rhodes 	kobject_put(gsmi_kobj);
1081*44e33a5aSSean Rhodes 	gsmi_buf_free(gsmi_dev.param_buf);
1082*44e33a5aSSean Rhodes 	gsmi_buf_free(gsmi_dev.data_buf);
1083*44e33a5aSSean Rhodes 	gsmi_buf_free(gsmi_dev.name_buf);
1084*44e33a5aSSean Rhodes 	kmem_cache_destroy(gsmi_dev.mem_pool);
1085*44e33a5aSSean Rhodes 	platform_device_unregister(gsmi_dev.pdev);
1086*44e33a5aSSean Rhodes #ifdef CONFIG_PM
1087*44e33a5aSSean Rhodes 	platform_driver_unregister(&gsmi_driver_info);
1088*44e33a5aSSean Rhodes #endif
1089*44e33a5aSSean Rhodes }
1090*44e33a5aSSean Rhodes 
1091*44e33a5aSSean Rhodes module_init(gsmi_init);
1092*44e33a5aSSean Rhodes module_exit(gsmi_exit);
1093*44e33a5aSSean Rhodes 
1094*44e33a5aSSean Rhodes MODULE_AUTHOR("Google, Inc.");
1095*44e33a5aSSean Rhodes MODULE_DESCRIPTION("EFI SMI interface for Google platforms");
1096*44e33a5aSSean Rhodes MODULE_LICENSE("GPL");
1097