Commit | Line | Data |
---|---|---|
14a43e69 BH |
1 | /* |
2 | * PowerNV OPAL API wrappers | |
3 | * | |
4 | * Copyright 2011 IBM Corp. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * as published by the Free Software Foundation; either version | |
9 | * 2 of the License, or (at your option) any later version. | |
10 | */ | |
11 | ||
58995a9a | 12 | #include <linux/jump_label.h> |
14a43e69 BH |
13 | #include <asm/ppc_asm.h> |
14 | #include <asm/hvcall.h> | |
15 | #include <asm/asm-offsets.h> | |
16 | #include <asm/opal.h> | |
c49f6353 AB |
17 | |
18 | .section ".text" | |
19 | ||
20 | #ifdef CONFIG_TRACEPOINTS | |
1bc9e47a | 21 | #ifdef HAVE_JUMP_LABEL |
c49f6353 AB |
22 | #define OPAL_BRANCH(LABEL) \ |
23 | ARCH_STATIC_BRANCH(LABEL, opal_tracepoint_key) | |
24 | #else | |
25 | ||
26 | .section ".toc","aw" | |
27 | ||
28 | .globl opal_tracepoint_refcount | |
29 | opal_tracepoint_refcount: | |
30 | .llong 0 | |
31 | ||
32 | .section ".text" | |
33 | ||
34 | /* | |
35 | * We branch around this in early init by using an unconditional cpu | |
36 | * feature. | |
37 | */ | |
38 | #define OPAL_BRANCH(LABEL) \ | |
39 | BEGIN_FTR_SECTION; \ | |
40 | b 1f; \ | |
41 | END_FTR_SECTION(0, 1); \ | |
42 | ld r12,opal_tracepoint_refcount@toc(r2); \ | |
c49f6353 AB |
43 | cmpdi r12,0; \ |
44 | bne- LABEL; \ | |
45 | 1: | |
46 | ||
47 | #endif | |
48 | ||
49 | #else | |
50 | #define OPAL_BRANCH(LABEL) | |
51 | #endif | |
14a43e69 BH |
52 | |
53 | /* TODO: | |
54 | * | |
55 | * - Trace irqs in/off (needs saving/restoring all args, argh...) | |
56 | * - Get r11 feed up by Dave so I can have better register usage | |
57 | */ | |
c49f6353 | 58 | |
14a43e69 | 59 | #define OPAL_CALL(name, token) \ |
19d36c21 | 60 | _GLOBAL_TOC(name); \ |
14a43e69 | 61 | mflr r0; \ |
69c592ed | 62 | std r0,PPC_LR_STKOFF(r1); \ |
c49f6353 AB |
63 | li r0,token; \ |
64 | OPAL_BRANCH(opal_tracepoint_entry) \ | |
65 | mfcr r12; \ | |
bbe30b3b | 66 | stw r12,8(r1); \ |
c49f6353 | 67 | li r11,0; \ |
14a43e69 | 68 | mfmsr r12; \ |
c49f6353 | 69 | ori r11,r11,MSR_EE; \ |
14a43e69 | 70 | std r12,PACASAVEDMSR(r13); \ |
c49f6353 | 71 | andc r12,r12,r11; \ |
14a43e69 | 72 | mtmsrd r12,1; \ |
c49f6353 AB |
73 | LOAD_REG_ADDR(r11,opal_return); \ |
74 | mtlr r11; \ | |
75 | li r11,MSR_DR|MSR_IR|MSR_LE;\ | |
76 | andc r12,r12,r11; \ | |
14a43e69 BH |
77 | mtspr SPRN_HSRR1,r12; \ |
78 | LOAD_REG_ADDR(r11,opal); \ | |
79 | ld r12,8(r11); \ | |
80 | ld r2,0(r11); \ | |
81 | mtspr SPRN_HSRR0,r12; \ | |
82 | hrfid | |
83 | ||
ad0289e4 | 84 | opal_return: |
be401b37 BH |
85 | /* |
86 | * Fixup endian on OPAL return... we should be able to simplify | |
87 | * this by instead converting the below trampoline to a set of | |
88 | * bytes (always BE) since MSR:LE will end up fixed up as a side | |
89 | * effect of the rfid. | |
90 | */ | |
91 | FIXUP_ENDIAN | |
14a43e69 | 92 | ld r2,PACATOC(r13); |
bbe30b3b | 93 | lwz r4,8(r1); |
69c592ed | 94 | ld r5,PPC_LR_STKOFF(r1); |
14a43e69 BH |
95 | ld r6,PACASAVEDMSR(r13); |
96 | mtspr SPRN_SRR0,r5; | |
97 | mtspr SPRN_SRR1,r6; | |
98 | mtcr r4; | |
99 | rfid | |
100 | ||
c49f6353 AB |
101 | #ifdef CONFIG_TRACEPOINTS |
102 | opal_tracepoint_entry: | |
103 | stdu r1,-STACKFRAMESIZE(r1) | |
104 | std r0,STK_REG(R23)(r1) | |
105 | std r3,STK_REG(R24)(r1) | |
106 | std r4,STK_REG(R25)(r1) | |
107 | std r5,STK_REG(R26)(r1) | |
108 | std r6,STK_REG(R27)(r1) | |
109 | std r7,STK_REG(R28)(r1) | |
110 | std r8,STK_REG(R29)(r1) | |
111 | std r9,STK_REG(R30)(r1) | |
112 | std r10,STK_REG(R31)(r1) | |
113 | mr r3,r0 | |
114 | addi r4,r1,STK_REG(R24) | |
115 | bl __trace_opal_entry | |
116 | ld r0,STK_REG(R23)(r1) | |
117 | ld r3,STK_REG(R24)(r1) | |
118 | ld r4,STK_REG(R25)(r1) | |
119 | ld r5,STK_REG(R26)(r1) | |
120 | ld r6,STK_REG(R27)(r1) | |
121 | ld r7,STK_REG(R28)(r1) | |
122 | ld r8,STK_REG(R29)(r1) | |
123 | ld r9,STK_REG(R30)(r1) | |
124 | ld r10,STK_REG(R31)(r1) | |
125 | LOAD_REG_ADDR(r11,opal_tracepoint_return) | |
126 | mfcr r12 | |
127 | std r11,16(r1) | |
128 | stw r12,8(r1) | |
c49f6353 AB |
129 | li r11,0 |
130 | mfmsr r12 | |
131 | ori r11,r11,MSR_EE | |
132 | std r12,PACASAVEDMSR(r13) | |
133 | andc r12,r12,r11 | |
134 | mtmsrd r12,1 | |
135 | LOAD_REG_ADDR(r11,opal_return) | |
136 | mtlr r11 | |
137 | li r11,MSR_DR|MSR_IR|MSR_LE | |
138 | andc r12,r12,r11 | |
139 | mtspr SPRN_HSRR1,r12 | |
140 | LOAD_REG_ADDR(r11,opal) | |
141 | ld r12,8(r11) | |
142 | ld r2,0(r11) | |
143 | mtspr SPRN_HSRR0,r12 | |
144 | hrfid | |
145 | ||
146 | opal_tracepoint_return: | |
147 | std r3,STK_REG(R31)(r1) | |
148 | mr r4,r3 | |
149 | ld r0,STK_REG(R23)(r1) | |
150 | bl __trace_opal_exit | |
151 | ld r3,STK_REG(R31)(r1) | |
152 | addi r1,r1,STACKFRAMESIZE | |
153 | ld r0,16(r1) | |
154 | mtlr r0 | |
155 | blr | |
156 | #endif | |
157 | ||
69c592ed BH |
158 | #define OPAL_CALL_REAL(name, token) \ |
159 | _GLOBAL_TOC(name); \ | |
160 | mflr r0; \ | |
161 | std r0,PPC_LR_STKOFF(r1); \ | |
162 | li r0,token; \ | |
163 | mfcr r12; \ | |
164 | stw r12,8(r1); \ | |
165 | \ | |
166 | /* Set opal return address */ \ | |
167 | LOAD_REG_ADDR(r11, opal_return_realmode); \ | |
168 | mtlr r11; \ | |
169 | mfmsr r12; \ | |
170 | li r11,MSR_LE; \ | |
171 | andc r12,r12,r11; \ | |
172 | mtspr SPRN_HSRR1,r12; \ | |
173 | LOAD_REG_ADDR(r11,opal); \ | |
174 | ld r12,8(r11); \ | |
175 | ld r2,0(r11); \ | |
176 | mtspr SPRN_HSRR0,r12; \ | |
7cba160a SP |
177 | hrfid |
178 | ||
69c592ed | 179 | opal_return_realmode: |
7cba160a | 180 | FIXUP_ENDIAN |
69c592ed BH |
181 | ld r2,PACATOC(r13); |
182 | lwz r11,8(r1); | |
7cba160a | 183 | ld r12,PPC_LR_STKOFF(r1) |
69c592ed | 184 | mtcr r11; |
7cba160a SP |
185 | mtlr r12 |
186 | blr | |
187 | ||
69c592ed | 188 | |
e28b05e7 | 189 | OPAL_CALL(opal_invalid_call, OPAL_INVALID_CALL); |
14a43e69 BH |
190 | OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE); |
191 | OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ); | |
192 | OPAL_CALL(opal_console_write_buffer_space, OPAL_CONSOLE_WRITE_BUFFER_SPACE); | |
193 | OPAL_CALL(opal_rtc_read, OPAL_RTC_READ); | |
194 | OPAL_CALL(opal_rtc_write, OPAL_RTC_WRITE); | |
195 | OPAL_CALL(opal_cec_power_down, OPAL_CEC_POWER_DOWN); | |
196 | OPAL_CALL(opal_cec_reboot, OPAL_CEC_REBOOT); | |
e784b649 | 197 | OPAL_CALL(opal_cec_reboot2, OPAL_CEC_REBOOT2); |
14a43e69 BH |
198 | OPAL_CALL(opal_read_nvram, OPAL_READ_NVRAM); |
199 | OPAL_CALL(opal_write_nvram, OPAL_WRITE_NVRAM); | |
200 | OPAL_CALL(opal_handle_interrupt, OPAL_HANDLE_INTERRUPT); | |
201 | OPAL_CALL(opal_poll_events, OPAL_POLL_EVENTS); | |
202 | OPAL_CALL(opal_pci_set_hub_tce_memory, OPAL_PCI_SET_HUB_TCE_MEMORY); | |
203 | OPAL_CALL(opal_pci_set_phb_tce_memory, OPAL_PCI_SET_PHB_TCE_MEMORY); | |
204 | OPAL_CALL(opal_pci_config_read_byte, OPAL_PCI_CONFIG_READ_BYTE); | |
205 | OPAL_CALL(opal_pci_config_read_half_word, OPAL_PCI_CONFIG_READ_HALF_WORD); | |
206 | OPAL_CALL(opal_pci_config_read_word, OPAL_PCI_CONFIG_READ_WORD); | |
207 | OPAL_CALL(opal_pci_config_write_byte, OPAL_PCI_CONFIG_WRITE_BYTE); | |
208 | OPAL_CALL(opal_pci_config_write_half_word, OPAL_PCI_CONFIG_WRITE_HALF_WORD); | |
209 | OPAL_CALL(opal_pci_config_write_word, OPAL_PCI_CONFIG_WRITE_WORD); | |
210 | OPAL_CALL(opal_set_xive, OPAL_SET_XIVE); | |
211 | OPAL_CALL(opal_get_xive, OPAL_GET_XIVE); | |
212 | OPAL_CALL(opal_register_exception_handler, OPAL_REGISTER_OPAL_EXCEPTION_HANDLER); | |
213 | OPAL_CALL(opal_pci_eeh_freeze_status, OPAL_PCI_EEH_FREEZE_STATUS); | |
214 | OPAL_CALL(opal_pci_eeh_freeze_clear, OPAL_PCI_EEH_FREEZE_CLEAR); | |
5ca27efb | 215 | OPAL_CALL(opal_pci_eeh_freeze_set, OPAL_PCI_EEH_FREEZE_SET); |
5b642340 | 216 | OPAL_CALL(opal_pci_err_inject, OPAL_PCI_ERR_INJECT); |
14a43e69 BH |
217 | OPAL_CALL(opal_pci_shpc, OPAL_PCI_SHPC); |
218 | OPAL_CALL(opal_pci_phb_mmio_enable, OPAL_PCI_PHB_MMIO_ENABLE); | |
219 | OPAL_CALL(opal_pci_set_phb_mem_window, OPAL_PCI_SET_PHB_MEM_WINDOW); | |
220 | OPAL_CALL(opal_pci_map_pe_mmio_window, OPAL_PCI_MAP_PE_MMIO_WINDOW); | |
221 | OPAL_CALL(opal_pci_set_phb_table_memory, OPAL_PCI_SET_PHB_TABLE_MEMORY); | |
222 | OPAL_CALL(opal_pci_set_pe, OPAL_PCI_SET_PE); | |
223 | OPAL_CALL(opal_pci_set_peltv, OPAL_PCI_SET_PELTV); | |
224 | OPAL_CALL(opal_pci_set_mve, OPAL_PCI_SET_MVE); | |
225 | OPAL_CALL(opal_pci_set_mve_enable, OPAL_PCI_SET_MVE_ENABLE); | |
226 | OPAL_CALL(opal_pci_get_xive_reissue, OPAL_PCI_GET_XIVE_REISSUE); | |
227 | OPAL_CALL(opal_pci_set_xive_reissue, OPAL_PCI_SET_XIVE_REISSUE); | |
228 | OPAL_CALL(opal_pci_set_xive_pe, OPAL_PCI_SET_XIVE_PE); | |
229 | OPAL_CALL(opal_get_xive_source, OPAL_GET_XIVE_SOURCE); | |
230 | OPAL_CALL(opal_get_msi_32, OPAL_GET_MSI_32); | |
231 | OPAL_CALL(opal_get_msi_64, OPAL_GET_MSI_64); | |
232 | OPAL_CALL(opal_start_cpu, OPAL_START_CPU); | |
233 | OPAL_CALL(opal_query_cpu_status, OPAL_QUERY_CPU_STATUS); | |
234 | OPAL_CALL(opal_write_oppanel, OPAL_WRITE_OPPANEL); | |
235 | OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); | |
236 | OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); | |
237 | OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); | |
f11fe552 BH |
238 | OPAL_CALL(opal_pci_get_hub_diag_data, OPAL_PCI_GET_HUB_DIAG_DATA); |
239 | OPAL_CALL(opal_pci_get_phb_diag_data, OPAL_PCI_GET_PHB_DIAG_DATA); | |
240 | OPAL_CALL(opal_pci_fence_phb, OPAL_PCI_FENCE_PHB); | |
241 | OPAL_CALL(opal_pci_reinit, OPAL_PCI_REINIT); | |
242 | OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR); | |
243 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); | |
244 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); | |
3b476aad | 245 | OPAL_CALL(opal_get_dpo_status, OPAL_GET_DPO_STATUS); |
f11fe552 | 246 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); |
23773230 GS |
247 | OPAL_CALL(opal_pci_next_error, OPAL_PCI_NEXT_ERROR); |
248 | OPAL_CALL(opal_pci_poll, OPAL_PCI_POLL); | |
137436c9 | 249 | OPAL_CALL(opal_pci_msi_eoi, OPAL_PCI_MSI_EOI); |
23773230 | 250 | OPAL_CALL(opal_pci_get_phb_diag_data2, OPAL_PCI_GET_PHB_DIAG_DATA2); |
cc0efb57 BH |
251 | OPAL_CALL(opal_xscom_read, OPAL_XSCOM_READ); |
252 | OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE); | |
253 | OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); | |
254 | OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); | |
13906db6 | 255 | OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); |
4926616c | 256 | OPAL_CALL(opal_reinit_cpus, OPAL_REINIT_CPUS); |
774fea1a SS |
257 | OPAL_CALL(opal_read_elog, OPAL_ELOG_READ); |
258 | OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK); | |
259 | OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE); | |
260 | OPAL_CALL(opal_resend_pending_logs, OPAL_ELOG_RESEND); | |
261 | OPAL_CALL(opal_write_elog, OPAL_ELOG_WRITE); | |
50bd6153 VH |
262 | OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE); |
263 | OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE); | |
264 | OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); | |
97eb001f | 265 | OPAL_CALL(opal_resync_timebase, OPAL_RESYNC_TIMEBASE); |
69c592ed | 266 | OPAL_CALL_REAL(opal_rm_resync_timebase, OPAL_RESYNC_TIMEBASE); |
bffe6bda | 267 | OPAL_CALL(opal_check_token, OPAL_CHECK_TOKEN); |
c7e64b9c SS |
268 | OPAL_CALL(opal_dump_init, OPAL_DUMP_INIT); |
269 | OPAL_CALL(opal_dump_info, OPAL_DUMP_INFO); | |
270 | OPAL_CALL(opal_dump_info2, OPAL_DUMP_INFO2); | |
271 | OPAL_CALL(opal_dump_read, OPAL_DUMP_READ); | |
272 | OPAL_CALL(opal_dump_ack, OPAL_DUMP_ACK); | |
24366360 | 273 | OPAL_CALL(opal_get_msg, OPAL_GET_MSG); |
43a1dd9b | 274 | OPAL_CALL(opal_write_oppanel_async, OPAL_WRITE_OPPANEL_ASYNC); |
24366360 | 275 | OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION); |
c7e64b9c | 276 | OPAL_CALL(opal_dump_resend_notification, OPAL_DUMP_RESEND); |
f7d98d18 | 277 | OPAL_CALL(opal_sync_host_reboot, OPAL_SYNC_HOST_REBOOT); |
7224adbb | 278 | OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ); |
4029cd66 NG |
279 | OPAL_CALL(opal_get_param, OPAL_GET_PARAM); |
280 | OPAL_CALL(opal_set_param, OPAL_SET_PARAM); | |
0ef95b41 | 281 | OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); |
69c592ed | 282 | OPAL_CALL_REAL(opal_rm_handle_hmi, OPAL_HANDLE_HMI); |
5703d2f4 | 283 | OPAL_CALL(opal_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE); |
69c592ed | 284 | OPAL_CALL_REAL(opal_rm_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE); |
77b54e9f | 285 | OPAL_CALL(opal_slw_set_reg, OPAL_SLW_SET_REG); |
b09c2ec4 VH |
286 | OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); |
287 | OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); | |
d7cf83fc | 288 | OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CAPI_MODE); |
16b1d26e NG |
289 | OPAL_CALL(opal_tpo_write, OPAL_WRITE_TPO); |
290 | OPAL_CALL(opal_tpo_read, OPAL_READ_TPO); | |
608b286d JK |
291 | OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND); |
292 | OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV); | |
47083450 | 293 | OPAL_CALL(opal_i2c_request, OPAL_I2C_REQUEST); |
ed59190e CB |
294 | OPAL_CALL(opal_flash_read, OPAL_FLASH_READ); |
295 | OPAL_CALL(opal_flash_write, OPAL_FLASH_WRITE); | |
296 | OPAL_CALL(opal_flash_erase, OPAL_FLASH_ERASE); | |
0d7cd855 | 297 | OPAL_CALL(opal_prd_msg, OPAL_PRD_MSG); |
8a8d9181 AK |
298 | OPAL_CALL(opal_leds_get_ind, OPAL_LEDS_GET_INDICATOR); |
299 | OPAL_CALL(opal_leds_set_ind, OPAL_LEDS_SET_INDICATOR); | |
affddff6 | 300 | OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH); |
ea0d856c GS |
301 | OPAL_CALL(opal_get_device_tree, OPAL_GET_DEVICE_TREE); |
302 | OPAL_CALL(opal_pci_get_presence_state, OPAL_PCI_GET_PRESENCE_STATE); | |
303 | OPAL_CALL(opal_pci_get_power_state, OPAL_PCI_GET_POWER_STATE); | |
304 | OPAL_CALL(opal_pci_set_power_state, OPAL_PCI_SET_POWER_STATE); | |
9fedd3f8 BH |
305 | OPAL_CALL(opal_int_get_xirr, OPAL_INT_GET_XIRR); |
306 | OPAL_CALL(opal_int_set_cppr, OPAL_INT_SET_CPPR); | |
307 | OPAL_CALL(opal_int_eoi, OPAL_INT_EOI); | |
308 | OPAL_CALL(opal_int_set_mfrr, OPAL_INT_SET_MFRR); | |
69c592ed BH |
309 | OPAL_CALL(opal_pci_tce_kill, OPAL_PCI_TCE_KILL); |
310 | OPAL_CALL_REAL(opal_rm_pci_tce_kill, OPAL_PCI_TCE_KILL); |