opal-wrappers.S 9.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 * 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.
 */

12
#include <linux/jump_label.h>
13 14 15 16
#include <asm/ppc_asm.h>
#include <asm/hvcall.h>
#include <asm/asm-offsets.h>
#include <asm/opal.h>
A
Anton Blanchard 已提交
17 18 19 20

	.section	".text"

#ifdef CONFIG_TRACEPOINTS
21
#ifdef HAVE_JUMP_LABEL
A
Anton Blanchard 已提交
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#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
52 53 54 55 56 57

/* TODO:
 *
 * - Trace irqs in/off (needs saving/restoring all args, argh...)
 * - Get r11 feed up by Dave so I can have better register usage
 */
A
Anton Blanchard 已提交
58

59
#define OPAL_CALL(name, token)		\
60
 _GLOBAL_TOC(name);			\
61 62
	mflr	r0;			\
	std	r0,16(r1);		\
A
Anton Blanchard 已提交
63 64 65
	li	r0,token;		\
	OPAL_BRANCH(opal_tracepoint_entry) \
	mfcr	r12;			\
66
	stw	r12,8(r1);		\
67
	std	r1,PACAR1(r13);		\
A
Anton Blanchard 已提交
68
	li	r11,0;			\
69
	mfmsr	r12;			\
A
Anton Blanchard 已提交
70
	ori	r11,r11,MSR_EE;		\
71
	std	r12,PACASAVEDMSR(r13);	\
A
Anton Blanchard 已提交
72
	andc	r12,r12,r11;		\
73
	mtmsrd	r12,1;			\
A
Anton Blanchard 已提交
74 75 76 77
	LOAD_REG_ADDR(r11,opal_return);	\
	mtlr	r11;			\
	li	r11,MSR_DR|MSR_IR|MSR_LE;\
	andc	r12,r12,r11;		\
78 79 80 81 82 83 84
	mtspr	SPRN_HSRR1,r12;		\
	LOAD_REG_ADDR(r11,opal);	\
	ld	r12,8(r11);		\
	ld	r2,0(r11);		\
	mtspr	SPRN_HSRR0,r12;		\
	hrfid

85
opal_return:
86 87 88 89 90 91 92
	/*
	 * 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
93
	ld	r2,PACATOC(r13);
94
	lwz	r4,8(r1);
95 96 97 98 99 100 101
	ld	r5,16(r1);
	ld	r6,PACASAVEDMSR(r13);
	mtspr	SPRN_SRR0,r5;
	mtspr	SPRN_SRR1,r6;
	mtcr	r4;
	rfid

A
Anton Blanchard 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
#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

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
/*
 * 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

197
OPAL_CALL(opal_invalid_call,			OPAL_INVALID_CALL);
198 199 200 201 202 203 204
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);
205
OPAL_CALL(opal_cec_reboot2,			OPAL_CEC_REBOOT2);
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
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);
G
Gavin Shan 已提交
223
OPAL_CALL(opal_pci_eeh_freeze_set,		OPAL_PCI_EEH_FREEZE_SET);
224
OPAL_CALL(opal_pci_err_inject,			OPAL_PCI_ERR_INJECT);
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
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);
246 247 248 249 250 251 252
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);
253
OPAL_CALL(opal_get_dpo_status,			OPAL_GET_DPO_STATUS);
254
OPAL_CALL(opal_set_system_attention_led,	OPAL_SET_SYSTEM_ATTENTION_LED);
255 256
OPAL_CALL(opal_pci_next_error,			OPAL_PCI_NEXT_ERROR);
OPAL_CALL(opal_pci_poll,			OPAL_PCI_POLL);
257
OPAL_CALL(opal_pci_msi_eoi,			OPAL_PCI_MSI_EOI);
258
OPAL_CALL(opal_pci_get_phb_diag_data2,		OPAL_PCI_GET_PHB_DIAG_DATA2);
259 260 261 262
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);
263
OPAL_CALL(opal_return_cpu,			OPAL_RETURN_CPU);
264
OPAL_CALL(opal_reinit_cpus,			OPAL_REINIT_CPUS);
265 266 267 268 269
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);
270 271 272
OPAL_CALL(opal_validate_flash,			OPAL_FLASH_VALIDATE);
OPAL_CALL(opal_manage_flash,			OPAL_FLASH_MANAGE);
OPAL_CALL(opal_update_flash,			OPAL_FLASH_UPDATE);
273
OPAL_CALL(opal_resync_timebase,			OPAL_RESYNC_TIMEBASE);
274
OPAL_CALL(opal_check_token,			OPAL_CHECK_TOKEN);
275 276 277 278 279
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);
280 281
OPAL_CALL(opal_get_msg,				OPAL_GET_MSG);
OPAL_CALL(opal_check_completion,		OPAL_CHECK_ASYNC_COMPLETION);
282
OPAL_CALL(opal_dump_resend_notification,	OPAL_DUMP_RESEND);
283
OPAL_CALL(opal_sync_host_reboot,		OPAL_SYNC_HOST_REBOOT);
284
OPAL_CALL(opal_sensor_read,			OPAL_SENSOR_READ);
285 286
OPAL_CALL(opal_get_param,			OPAL_GET_PARAM);
OPAL_CALL(opal_set_param,			OPAL_SET_PARAM);
287
OPAL_CALL(opal_handle_hmi,			OPAL_HANDLE_HMI);
288
OPAL_CALL(opal_config_cpu_idle_state,		OPAL_CONFIG_CPU_IDLE_STATE);
289
OPAL_CALL(opal_slw_set_reg,			OPAL_SLW_SET_REG);
290 291
OPAL_CALL(opal_register_dump_region,		OPAL_REGISTER_DUMP_REGION);
OPAL_CALL(opal_unregister_dump_region,		OPAL_UNREGISTER_DUMP_REGION);
292
OPAL_CALL(opal_pci_set_phb_cxl_mode,		OPAL_PCI_SET_PHB_CAPI_MODE);
293 294
OPAL_CALL(opal_tpo_write,			OPAL_WRITE_TPO);
OPAL_CALL(opal_tpo_read,			OPAL_READ_TPO);
295 296
OPAL_CALL(opal_ipmi_send,			OPAL_IPMI_SEND);
OPAL_CALL(opal_ipmi_recv,			OPAL_IPMI_RECV);
297
OPAL_CALL(opal_i2c_request,			OPAL_I2C_REQUEST);
298 299 300
OPAL_CALL(opal_flash_read,			OPAL_FLASH_READ);
OPAL_CALL(opal_flash_write,			OPAL_FLASH_WRITE);
OPAL_CALL(opal_flash_erase,			OPAL_FLASH_ERASE);
301
OPAL_CALL(opal_prd_msg,				OPAL_PRD_MSG);