| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | /* | 
					
						
							|  |  |  |  * PowerNV OPAL API wrappers | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright 2011 IBM Corp. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or
 | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version
 | 
					
						
							|  |  |  |  * 2 of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <asm/ppc_asm.h> | 
					
						
							|  |  |  | #include <asm/hvcall.h> | 
					
						
							|  |  |  | #include <asm/asm-offsets.h> | 
					
						
							|  |  |  | #include <asm/opal.h> | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | #include <asm/jump_label.h> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.section	".text" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_TRACEPOINTS | 
					
						
							| 
									
										
										
										
											2014-10-30 15:43:43 +11:00
										 |  |  | #ifdef HAVE_JUMP_LABEL | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | #define OPAL_BRANCH(LABEL)					\ | 
					
						
							|  |  |  | 	ARCH_STATIC_BRANCH(LABEL, opal_tracepoint_key) | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.section	".toc","aw" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.globl opal_tracepoint_refcount
 | 
					
						
							|  |  |  | opal_tracepoint_refcount: | 
					
						
							|  |  |  | 	.llong	0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.section	".text" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * We branch around this in early init by using an unconditional cpu | 
					
						
							|  |  |  |  * feature. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define OPAL_BRANCH(LABEL)					\ | 
					
						
							|  |  |  | BEGIN_FTR_SECTION;						\
 | 
					
						
							|  |  |  | 	b	1f;						\
 | 
					
						
							|  |  |  | END_FTR_SECTION(0, 1);						\
 | 
					
						
							|  |  |  | 	ld	r12,opal_tracepoint_refcount@toc(r2);		\
 | 
					
						
							|  |  |  | 	cmpdi	r12,0;						\
 | 
					
						
							|  |  |  | 	bne-	LABEL;						\
 | 
					
						
							|  |  |  | 1: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | #define OPAL_BRANCH(LABEL) | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* TODO: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - Trace irqs in/off (needs saving/restoring all args, argh...) | 
					
						
							|  |  |  |  * - Get r11 feed up by Dave so I can have better register usage | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | #define OPAL_CALL(name, token)		\ | 
					
						
							| 
									
										
										
										
											2014-10-22 11:32:52 +08:00
										 |  |  |  _GLOBAL_TOC(name);			\
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 	mflr	r0;			\
 | 
					
						
							|  |  |  | 	std	r0,16(r1);		\
 | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | 	li	r0,token;		\
 | 
					
						
							|  |  |  | 	OPAL_BRANCH(opal_tracepoint_entry) \ | 
					
						
							|  |  |  | 	mfcr	r12;			\
 | 
					
						
							| 
									
										
										
										
											2013-10-15 14:36:31 +11:00
										 |  |  | 	stw	r12,8(r1);		\
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 	std	r1,PACAR1(r13);		\
 | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | 	li	r11,0;			\
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 	mfmsr	r12;			\
 | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | 	ori	r11,r11,MSR_EE;		\
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 	std	r12,PACASAVEDMSR(r13);	\
 | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | 	andc	r12,r12,r11;		\
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 	mtmsrd	r12,1;			\
 | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | 	LOAD_REG_ADDR(r11,opal_return);	\
 | 
					
						
							|  |  |  | 	mtlr	r11;			\
 | 
					
						
							|  |  |  | 	li	r11,MSR_DR|MSR_IR|MSR_LE;\
 | 
					
						
							|  |  |  | 	andc	r12,r12,r11;		\
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 	mtspr	SPRN_HSRR1,r12;		\
 | 
					
						
							|  |  |  | 	LOAD_REG_ADDR(r11,opal);	\
 | 
					
						
							|  |  |  | 	ld	r12,8(r11);		\
 | 
					
						
							|  |  |  | 	ld	r2,0(r11);		\
 | 
					
						
							|  |  |  | 	mtspr	SPRN_HSRR0,r12;		\
 | 
					
						
							|  |  |  | 	hrfid | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-04 16:04:52 +11:00
										 |  |  | opal_return: | 
					
						
							| 
									
										
										
										
											2013-09-23 12:05:03 +10:00
										 |  |  | 	/* | 
					
						
							|  |  |  | 	 * Fixup endian on OPAL return... we should be able to simplify | 
					
						
							|  |  |  | 	 * this by instead converting the below trampoline to a set of | 
					
						
							|  |  |  | 	 * bytes (always BE) since MSR:LE will end up fixed up as a side | 
					
						
							|  |  |  | 	 * effect of the rfid. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	FIXUP_ENDIAN | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 	ld	r2,PACATOC(r13);
 | 
					
						
							| 
									
										
										
										
											2013-10-15 14:36:31 +11:00
										 |  |  | 	lwz	r4,8(r1);
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | 	ld	r5,16(r1);
 | 
					
						
							|  |  |  | 	ld	r6,PACASAVEDMSR(r13);
 | 
					
						
							|  |  |  | 	mtspr	SPRN_SRR0,r5;
 | 
					
						
							|  |  |  | 	mtspr	SPRN_SRR1,r6;
 | 
					
						
							|  |  |  | 	mtcr	r4;
 | 
					
						
							|  |  |  | 	rfid | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 17:20:50 +10:00
										 |  |  | #ifdef CONFIG_TRACEPOINTS | 
					
						
							|  |  |  | opal_tracepoint_entry: | 
					
						
							|  |  |  | 	stdu	r1,-STACKFRAMESIZE(r1) | 
					
						
							|  |  |  | 	std	r0,STK_REG(R23)(r1) | 
					
						
							|  |  |  | 	std	r3,STK_REG(R24)(r1) | 
					
						
							|  |  |  | 	std	r4,STK_REG(R25)(r1) | 
					
						
							|  |  |  | 	std	r5,STK_REG(R26)(r1) | 
					
						
							|  |  |  | 	std	r6,STK_REG(R27)(r1) | 
					
						
							|  |  |  | 	std	r7,STK_REG(R28)(r1) | 
					
						
							|  |  |  | 	std	r8,STK_REG(R29)(r1) | 
					
						
							|  |  |  | 	std	r9,STK_REG(R30)(r1) | 
					
						
							|  |  |  | 	std	r10,STK_REG(R31)(r1) | 
					
						
							|  |  |  | 	mr	r3,r0 | 
					
						
							|  |  |  | 	addi	r4,r1,STK_REG(R24) | 
					
						
							|  |  |  | 	bl	__trace_opal_entry | 
					
						
							|  |  |  | 	ld	r0,STK_REG(R23)(r1) | 
					
						
							|  |  |  | 	ld	r3,STK_REG(R24)(r1) | 
					
						
							|  |  |  | 	ld	r4,STK_REG(R25)(r1) | 
					
						
							|  |  |  | 	ld	r5,STK_REG(R26)(r1) | 
					
						
							|  |  |  | 	ld	r6,STK_REG(R27)(r1) | 
					
						
							|  |  |  | 	ld	r7,STK_REG(R28)(r1) | 
					
						
							|  |  |  | 	ld	r8,STK_REG(R29)(r1) | 
					
						
							|  |  |  | 	ld	r9,STK_REG(R30)(r1) | 
					
						
							|  |  |  | 	ld	r10,STK_REG(R31)(r1) | 
					
						
							|  |  |  | 	LOAD_REG_ADDR(r11,opal_tracepoint_return) | 
					
						
							|  |  |  | 	mfcr	r12 | 
					
						
							|  |  |  | 	std	r11,16(r1) | 
					
						
							|  |  |  | 	stw	r12,8(r1) | 
					
						
							|  |  |  | 	std	r1,PACAR1(r13) | 
					
						
							|  |  |  | 	li	r11,0 | 
					
						
							|  |  |  | 	mfmsr	r12 | 
					
						
							|  |  |  | 	ori	r11,r11,MSR_EE | 
					
						
							|  |  |  | 	std	r12,PACASAVEDMSR(r13) | 
					
						
							|  |  |  | 	andc	r12,r12,r11 | 
					
						
							|  |  |  | 	mtmsrd	r12,1 | 
					
						
							|  |  |  | 	LOAD_REG_ADDR(r11,opal_return) | 
					
						
							|  |  |  | 	mtlr	r11 | 
					
						
							|  |  |  | 	li	r11,MSR_DR|MSR_IR|MSR_LE | 
					
						
							|  |  |  | 	andc	r12,r12,r11 | 
					
						
							|  |  |  | 	mtspr	SPRN_HSRR1,r12 | 
					
						
							|  |  |  | 	LOAD_REG_ADDR(r11,opal) | 
					
						
							|  |  |  | 	ld	r12,8(r11) | 
					
						
							|  |  |  | 	ld	r2,0(r11) | 
					
						
							|  |  |  | 	mtspr	SPRN_HSRR0,r12 | 
					
						
							|  |  |  | 	hrfid | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | opal_tracepoint_return: | 
					
						
							|  |  |  | 	std	r3,STK_REG(R31)(r1) | 
					
						
							|  |  |  | 	mr	r4,r3 | 
					
						
							|  |  |  | 	ld	r0,STK_REG(R23)(r1) | 
					
						
							|  |  |  | 	bl	__trace_opal_exit | 
					
						
							|  |  |  | 	ld	r3,STK_REG(R31)(r1) | 
					
						
							|  |  |  | 	addi	r1,r1,STACKFRAMESIZE | 
					
						
							|  |  |  | 	ld	r0,16(r1) | 
					
						
							|  |  |  | 	mtlr	r0 | 
					
						
							|  |  |  | 	blr | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 00:26:52 +05:30
										 |  |  | /* | 
					
						
							|  |  |  |  * Make opal call in realmode. This is a generic function to be called | 
					
						
							|  |  |  |  * from realmode. It handles endianness. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * r13 - paca pointer | 
					
						
							|  |  |  |  * r1  - stack pointer | 
					
						
							|  |  |  |  * r0  - opal token | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | _GLOBAL(opal_call_realmode) | 
					
						
							|  |  |  | 	mflr	r12 | 
					
						
							|  |  |  | 	std	r12,PPC_LR_STKOFF(r1) | 
					
						
							|  |  |  | 	ld	r2,PACATOC(r13) | 
					
						
							|  |  |  | 	/* Set opal return address */ | 
					
						
							|  |  |  | 	LOAD_REG_ADDR(r12,return_from_opal_call) | 
					
						
							|  |  |  | 	mtlr	r12 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mfmsr	r12 | 
					
						
							|  |  |  | #ifdef __LITTLE_ENDIAN__ | 
					
						
							|  |  |  | 	/* Handle endian-ness */ | 
					
						
							|  |  |  | 	li	r11,MSR_LE | 
					
						
							|  |  |  | 	andc	r12,r12,r11 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 	mtspr	SPRN_HSRR1,r12 | 
					
						
							|  |  |  | 	LOAD_REG_ADDR(r11,opal) | 
					
						
							|  |  |  | 	ld	r12,8(r11) | 
					
						
							|  |  |  | 	ld	r2,0(r11) | 
					
						
							|  |  |  | 	mtspr	SPRN_HSRR0,r12 | 
					
						
							|  |  |  | 	hrfid | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | return_from_opal_call: | 
					
						
							|  |  |  | #ifdef __LITTLE_ENDIAN__ | 
					
						
							|  |  |  | 	FIXUP_ENDIAN | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 	ld	r12,PPC_LR_STKOFF(r1) | 
					
						
							|  |  |  | 	mtlr	r12 | 
					
						
							|  |  |  | 	blr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-01 14:28:20 +10:30
										 |  |  | OPAL_CALL(opal_invalid_call,			OPAL_INVALID_CALL);
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | OPAL_CALL(opal_console_write,			OPAL_CONSOLE_WRITE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_console_read,			OPAL_CONSOLE_READ);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_console_write_buffer_space,	OPAL_CONSOLE_WRITE_BUFFER_SPACE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_rtc_read,			OPAL_RTC_READ);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_rtc_write,			OPAL_RTC_WRITE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_cec_power_down,			OPAL_CEC_POWER_DOWN);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_cec_reboot,			OPAL_CEC_REBOOT);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_read_nvram,			OPAL_READ_NVRAM);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_write_nvram,			OPAL_WRITE_NVRAM);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_handle_interrupt,		OPAL_HANDLE_INTERRUPT);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_poll_events,			OPAL_POLL_EVENTS);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_hub_tce_memory,		OPAL_PCI_SET_HUB_TCE_MEMORY);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_phb_tce_memory,		OPAL_PCI_SET_PHB_TCE_MEMORY);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_config_read_byte,		OPAL_PCI_CONFIG_READ_BYTE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_config_read_half_word,	OPAL_PCI_CONFIG_READ_HALF_WORD);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_config_read_word,		OPAL_PCI_CONFIG_READ_WORD);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_config_write_byte,		OPAL_PCI_CONFIG_WRITE_BYTE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_config_write_half_word,	OPAL_PCI_CONFIG_WRITE_HALF_WORD);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_config_write_word,		OPAL_PCI_CONFIG_WRITE_WORD);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_set_xive,			OPAL_SET_XIVE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_get_xive,			OPAL_GET_XIVE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_register_exception_handler,	OPAL_REGISTER_OPAL_EXCEPTION_HANDLER);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_eeh_freeze_status,		OPAL_PCI_EEH_FREEZE_STATUS);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_eeh_freeze_clear,		OPAL_PCI_EEH_FREEZE_CLEAR);
 | 
					
						
							| 
									
										
										
										
											2014-07-21 14:42:31 +10:00
										 |  |  | OPAL_CALL(opal_pci_eeh_freeze_set,		OPAL_PCI_EEH_FREEZE_SET);
 | 
					
						
							| 
									
										
										
										
											2014-09-30 12:38:55 +10:00
										 |  |  | OPAL_CALL(opal_pci_err_inject,			OPAL_PCI_ERR_INJECT);
 | 
					
						
							| 
									
										
										
										
											2011-09-19 17:44:57 +00:00
										 |  |  | OPAL_CALL(opal_pci_shpc,			OPAL_PCI_SHPC);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_phb_mmio_enable,		OPAL_PCI_PHB_MMIO_ENABLE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_phb_mem_window,		OPAL_PCI_SET_PHB_MEM_WINDOW);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_map_pe_mmio_window,		OPAL_PCI_MAP_PE_MMIO_WINDOW);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_phb_table_memory,	OPAL_PCI_SET_PHB_TABLE_MEMORY);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_pe,			OPAL_PCI_SET_PE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_peltv,			OPAL_PCI_SET_PELTV);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_mve,			OPAL_PCI_SET_MVE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_mve_enable,		OPAL_PCI_SET_MVE_ENABLE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_get_xive_reissue,		OPAL_PCI_GET_XIVE_REISSUE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_xive_reissue,		OPAL_PCI_SET_XIVE_REISSUE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_set_xive_pe,			OPAL_PCI_SET_XIVE_PE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_get_xive_source,			OPAL_GET_XIVE_SOURCE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_get_msi_32,			OPAL_GET_MSI_32);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_get_msi_64,			OPAL_GET_MSI_64);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_start_cpu,			OPAL_START_CPU);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_query_cpu_status,		OPAL_QUERY_CPU_STATUS);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_write_oppanel,			OPAL_WRITE_OPPANEL);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_map_pe_dma_window,		OPAL_PCI_MAP_PE_DMA_WINDOW);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_map_pe_dma_window_real,	OPAL_PCI_MAP_PE_DMA_WINDOW_REAL);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_reset,			OPAL_PCI_RESET);
 | 
					
						
							| 
									
										
										
										
											2011-11-29 18:22:50 +00:00
										 |  |  | OPAL_CALL(opal_pci_get_hub_diag_data,		OPAL_PCI_GET_HUB_DIAG_DATA);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_get_phb_diag_data,		OPAL_PCI_GET_PHB_DIAG_DATA);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_fence_phb,			OPAL_PCI_FENCE_PHB);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_reinit,			OPAL_PCI_REINIT);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_mask_pe_error,		OPAL_PCI_MASK_PE_ERROR);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_set_slot_led_status,		OPAL_SET_SLOT_LED_STATUS);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_get_epow_status,			OPAL_GET_EPOW_STATUS);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_set_system_attention_led,	OPAL_SET_SYSTEM_ATTENTION_LED);
 | 
					
						
							| 
									
										
										
										
											2013-06-20 13:21:05 +08:00
										 |  |  | OPAL_CALL(opal_pci_next_error,			OPAL_PCI_NEXT_ERROR);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_pci_poll,			OPAL_PCI_POLL);
 | 
					
						
							| 
									
										
										
										
											2013-04-25 19:20:59 +00:00
										 |  |  | OPAL_CALL(opal_pci_msi_eoi,			OPAL_PCI_MSI_EOI);
 | 
					
						
							| 
									
										
										
										
											2013-06-20 13:21:05 +08:00
										 |  |  | OPAL_CALL(opal_pci_get_phb_diag_data2,		OPAL_PCI_GET_PHB_DIAG_DATA2);
 | 
					
						
							| 
									
										
										
										
											2013-07-15 13:03:09 +10:00
										 |  |  | OPAL_CALL(opal_xscom_read,			OPAL_XSCOM_READ);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_xscom_write,			OPAL_XSCOM_WRITE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_lpc_read,			OPAL_LPC_READ);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_lpc_write,			OPAL_LPC_WRITE);
 | 
					
						
							| 
									
										
										
										
											2013-08-21 13:03:20 +10:00
										 |  |  | OPAL_CALL(opal_return_cpu,			OPAL_RETURN_CPU);
 | 
					
						
							| 
									
										
										
										
											2014-05-20 11:01:28 +10:00
										 |  |  | OPAL_CALL(opal_reinit_cpus,			OPAL_REINIT_CPUS);
 | 
					
						
							| 
									
										
											  
											
												powerpc/powernv: Read OPAL error log and export it through sysfs
Based on a patch by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
This patch adds support to read error logs from OPAL and export
them to userspace through a sysfs interface.
We export each log entry as a directory in /sys/firmware/opal/elog/
Currently, OPAL will buffer up to 128 error log records, we don't
need to have any knowledge of this limit on the Linux side as that
is actually largely transparent to us.
Each error log entry has the following files: id, type, acknowledge, raw.
Currently we just export the raw binary error log in the 'raw' attribute.
In a future patch, we may parse more of the error log to make it a bit
easier for userspace (e.g. to be able to display a brief summary in
petitboot without having to have a full parser).
If we have >128 logs from OPAL, we'll only be notified of 128 until
userspace starts acknowledging them. This limitation may be lifted in
the future and with this patch, that should "just work" from the linux side.
A userspace daemon should:
- wait for error log entries using normal mechanisms (we announce creation)
- read error log entry
- save error log entry safely to disk
- acknowledge the error log entry
- rinse, repeat.
On the Linux side, we read the error log when we're notified of it. This
possibly isn't ideal as it would be better to only read them on-demand.
However, this doesn't really work with current OPAL interface, so we
read the error log immediately when notified at the moment.
I've tested this pretty extensively and am rather confident that the
linux side of things works rather well. There is currently an issue with
the service processor side of things for >128 error logs though.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
											
										 
											2014-02-28 11:58:32 +11:00
										 |  |  | OPAL_CALL(opal_read_elog,			OPAL_ELOG_READ);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_send_ack_elog,			OPAL_ELOG_ACK);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_get_elog_size,			OPAL_ELOG_SIZE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_resend_pending_logs,		OPAL_ELOG_RESEND);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_write_elog,			OPAL_ELOG_WRITE);
 | 
					
						
							| 
									
										
										
										
											2013-10-24 16:04:58 +05:30
										 |  |  | OPAL_CALL(opal_validate_flash,			OPAL_FLASH_VALIDATE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_manage_flash,			OPAL_FLASH_MANAGE);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_update_flash,			OPAL_FLASH_UPDATE);
 | 
					
						
							| 
									
										
										
										
											2014-02-26 05:38:43 +05:30
										 |  |  | OPAL_CALL(opal_resync_timebase,			OPAL_RESYNC_TIMEBASE);
 | 
					
						
							| 
									
										
										
										
											2014-08-19 14:47:59 +10:00
										 |  |  | OPAL_CALL(opal_check_token,			OPAL_CHECK_TOKEN);
 | 
					
						
							| 
									
										
										
										
											2014-03-03 10:25:42 +11:00
										 |  |  | OPAL_CALL(opal_dump_init,			OPAL_DUMP_INIT);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_dump_info,			OPAL_DUMP_INFO);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_dump_info2,			OPAL_DUMP_INFO2);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_dump_read,			OPAL_DUMP_READ);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_dump_ack,			OPAL_DUMP_ACK);
 | 
					
						
							| 
									
										
										
										
											2013-11-18 15:35:58 +05:30
										 |  |  | OPAL_CALL(opal_get_msg,				OPAL_GET_MSG);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_check_completion,		OPAL_CHECK_ASYNC_COMPLETION);
 | 
					
						
							| 
									
										
										
										
											2014-03-03 10:25:42 +11:00
										 |  |  | OPAL_CALL(opal_dump_resend_notification,	OPAL_DUMP_RESEND);
 | 
					
						
							| 
									
										
										
										
											2014-01-15 17:02:04 +11:00
										 |  |  | OPAL_CALL(opal_sync_host_reboot,		OPAL_SYNC_HOST_REBOOT);
 | 
					
						
							| 
									
										
										
										
											2014-03-07 11:03:27 +05:30
										 |  |  | OPAL_CALL(opal_sensor_read,			OPAL_SENSOR_READ);
 | 
					
						
							| 
									
										
										
										
											2014-03-07 11:02:09 +05:30
										 |  |  | OPAL_CALL(opal_get_param,			OPAL_GET_PARAM);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_set_param,			OPAL_SET_PARAM);
 | 
					
						
							| 
									
										
										
										
											2014-07-29 18:40:07 +05:30
										 |  |  | OPAL_CALL(opal_handle_hmi,			OPAL_HANDLE_HMI);
 | 
					
						
							| 
									
										
										
										
											2014-12-10 00:26:53 +05:30
										 |  |  | OPAL_CALL(opal_slw_set_reg,			OPAL_SLW_SET_REG);
 | 
					
						
							| 
									
										
										
										
											2014-08-09 11:15:45 +05:30
										 |  |  | OPAL_CALL(opal_register_dump_region,		OPAL_REGISTER_DUMP_REGION);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_unregister_dump_region,		OPAL_UNREGISTER_DUMP_REGION);
 | 
					
						
							| 
									
										
										
										
											2014-10-08 19:54:59 +11:00
										 |  |  | OPAL_CALL(opal_pci_set_phb_cxl_mode,		OPAL_PCI_SET_PHB_CXL_MODE);
 | 
					
						
							| 
									
										
										
										
											2014-10-14 14:08:36 +05:30
										 |  |  | OPAL_CALL(opal_tpo_write,			OPAL_WRITE_TPO);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_tpo_read,			OPAL_READ_TPO);
 | 
					
						
							| 
									
										
										
										
											2014-11-06 11:38:27 +08:00
										 |  |  | OPAL_CALL(opal_ipmi_send,			OPAL_IPMI_SEND);
 | 
					
						
							|  |  |  | OPAL_CALL(opal_ipmi_recv,			OPAL_IPMI_RECV);
 | 
					
						
							| 
									
										
										
										
											2014-12-13 23:31:05 +05:30
										 |  |  | OPAL_CALL(opal_i2c_request,			OPAL_I2C_REQUEST);
 |