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 | ||
12 | #include <asm/ppc_asm.h> | |
13 | #include <asm/hvcall.h> | |
14 | #include <asm/asm-offsets.h> | |
15 | #include <asm/opal.h> | |
c49f6353 AB |
16 | #include <asm/jump_label.h> |
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); \ | |
43 | std r12,32(r1); \ | |
44 | cmpdi r12,0; \ | |
45 | bne- LABEL; \ | |
46 | 1: | |
47 | ||
48 | #endif | |
49 | ||
50 | #else | |
51 | #define OPAL_BRANCH(LABEL) | |
52 | #endif | |
14a43e69 BH |
53 | |
54 | /* TODO: | |
55 | * | |
56 | * - Trace irqs in/off (needs saving/restoring all args, argh...) | |
57 | * - Get r11 feed up by Dave so I can have better register usage | |
58 | */ | |
c49f6353 | 59 | |
14a43e69 | 60 | #define OPAL_CALL(name, token) \ |
19d36c21 | 61 | _GLOBAL_TOC(name); \ |
14a43e69 | 62 | mflr r0; \ |
14a43e69 | 63 | std r0,16(r1); \ |
c49f6353 AB |
64 | li r0,token; \ |
65 | OPAL_BRANCH(opal_tracepoint_entry) \ | |
66 | mfcr r12; \ | |
bbe30b3b | 67 | stw r12,8(r1); \ |
14a43e69 | 68 | std r1,PACAR1(r13); \ |
c49f6353 | 69 | li r11,0; \ |
14a43e69 | 70 | mfmsr r12; \ |
c49f6353 | 71 | ori r11,r11,MSR_EE; \ |
14a43e69 | 72 | std r12,PACASAVEDMSR(r13); \ |
c49f6353 | 73 | andc r12,r12,r11; \ |
14a43e69 | 74 | mtmsrd r12,1; \ |
c49f6353 AB |
75 | LOAD_REG_ADDR(r11,opal_return); \ |
76 | mtlr r11; \ | |
77 | li r11,MSR_DR|MSR_IR|MSR_LE;\ | |
78 | andc r12,r12,r11; \ | |
14a43e69 BH |
79 | mtspr SPRN_HSRR1,r12; \ |
80 | LOAD_REG_ADDR(r11,opal); \ | |
81 | ld r12,8(r11); \ | |
82 | ld r2,0(r11); \ | |
83 | mtspr SPRN_HSRR0,r12; \ | |
84 | hrfid | |
85 | ||
ad0289e4 | 86 | opal_return: |
be401b37 BH |
87 | /* |
88 | * Fixup endian on OPAL return... we should be able to simplify | |
89 | * this by instead converting the below trampoline to a set of | |
90 | * bytes (always BE) since MSR:LE will end up fixed up as a side | |
91 | * effect of the rfid. | |
92 | */ | |
93 | FIXUP_ENDIAN | |
14a43e69 | 94 | ld r2,PACATOC(r13); |
bbe30b3b | 95 | lwz r4,8(r1); |
14a43e69 BH |
96 | ld r5,16(r1); |
97 | ld r6,PACASAVEDMSR(r13); | |
98 | mtspr SPRN_SRR0,r5; | |
99 | mtspr SPRN_SRR1,r6; | |
100 | mtcr r4; | |
101 | rfid | |
102 | ||
c49f6353 AB |
103 | #ifdef CONFIG_TRACEPOINTS |
104 | opal_tracepoint_entry: | |
105 | stdu r1,-STACKFRAMESIZE(r1) | |
106 | std r0,STK_REG(R23)(r1) | |
107 | std r3,STK_REG(R24)(r1) | |
108 | std r4,STK_REG(R25)(r1) | |
109 | std r5,STK_REG(R26)(r1) | |
110 | std r6,STK_REG(R27)(r1) | |
111 | std r7,STK_REG(R28)(r1) | |
112 | std r8,STK_REG(R29)(r1) | |
113 | std r9,STK_REG(R30)(r1) | |
114 | std r10,STK_REG(R31)(r1) | |
115 | mr r3,r0 | |
116 | addi r4,r1,STK_REG(R24) | |
117 | bl __trace_opal_entry | |
118 | ld r0,STK_REG(R23)(r1) | |
119 | ld r3,STK_REG(R24)(r1) | |
120 | ld r4,STK_REG(R25)(r1) | |
121 | ld r5,STK_REG(R26)(r1) | |
122 | ld r6,STK_REG(R27)(r1) | |
123 | ld r7,STK_REG(R28)(r1) | |
124 | ld r8,STK_REG(R29)(r1) | |
125 | ld r9,STK_REG(R30)(r1) | |
126 | ld r10,STK_REG(R31)(r1) | |
127 | LOAD_REG_ADDR(r11,opal_tracepoint_return) | |
128 | mfcr r12 | |
129 | std r11,16(r1) | |
130 | stw r12,8(r1) | |
131 | std r1,PACAR1(r13) | |
132 | li r11,0 | |
133 | mfmsr r12 | |
134 | ori r11,r11,MSR_EE | |
135 | std r12,PACASAVEDMSR(r13) | |
136 | andc r12,r12,r11 | |
137 | mtmsrd r12,1 | |
138 | LOAD_REG_ADDR(r11,opal_return) | |
139 | mtlr r11 | |
140 | li r11,MSR_DR|MSR_IR|MSR_LE | |
141 | andc r12,r12,r11 | |
142 | mtspr SPRN_HSRR1,r12 | |
143 | LOAD_REG_ADDR(r11,opal) | |
144 | ld r12,8(r11) | |
145 | ld r2,0(r11) | |
146 | mtspr SPRN_HSRR0,r12 | |
147 | hrfid | |
148 | ||
149 | opal_tracepoint_return: | |
150 | std r3,STK_REG(R31)(r1) | |
151 | mr r4,r3 | |
152 | ld r0,STK_REG(R23)(r1) | |
153 | bl __trace_opal_exit | |
154 | ld r3,STK_REG(R31)(r1) | |
155 | addi r1,r1,STACKFRAMESIZE | |
156 | ld r0,16(r1) | |
157 | mtlr r0 | |
158 | blr | |
159 | #endif | |
160 | ||
7cba160a SP |
161 | /* |
162 | * Make opal call in realmode. This is a generic function to be called | |
163 | * from realmode. It handles endianness. | |
164 | * | |
165 | * r13 - paca pointer | |
166 | * r1 - stack pointer | |
167 | * r0 - opal token | |
168 | */ | |
169 | _GLOBAL(opal_call_realmode) | |
170 | mflr r12 | |
171 | std r12,PPC_LR_STKOFF(r1) | |
172 | ld r2,PACATOC(r13) | |
173 | /* Set opal return address */ | |
174 | LOAD_REG_ADDR(r12,return_from_opal_call) | |
175 | mtlr r12 | |
176 | ||
177 | mfmsr r12 | |
178 | #ifdef __LITTLE_ENDIAN__ | |
179 | /* Handle endian-ness */ | |
180 | li r11,MSR_LE | |
181 | andc r12,r12,r11 | |
182 | #endif | |
183 | mtspr SPRN_HSRR1,r12 | |
184 | LOAD_REG_ADDR(r11,opal) | |
185 | ld r12,8(r11) | |
186 | ld r2,0(r11) | |
187 | mtspr SPRN_HSRR0,r12 | |
188 | hrfid | |
189 | ||
190 | return_from_opal_call: | |
191 | #ifdef __LITTLE_ENDIAN__ | |
192 | FIXUP_ENDIAN | |
193 | #endif | |
194 | ld r12,PPC_LR_STKOFF(r1) | |
195 | mtlr r12 | |
196 | blr | |
197 | ||
e28b05e7 | 198 | OPAL_CALL(opal_invalid_call, OPAL_INVALID_CALL); |
14a43e69 BH |
199 | OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE); |
200 | OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ); | |
201 | OPAL_CALL(opal_console_write_buffer_space, OPAL_CONSOLE_WRITE_BUFFER_SPACE); | |
202 | OPAL_CALL(opal_rtc_read, OPAL_RTC_READ); | |
203 | OPAL_CALL(opal_rtc_write, OPAL_RTC_WRITE); | |
204 | OPAL_CALL(opal_cec_power_down, OPAL_CEC_POWER_DOWN); | |
205 | OPAL_CALL(opal_cec_reboot, OPAL_CEC_REBOOT); | |
206 | OPAL_CALL(opal_read_nvram, OPAL_READ_NVRAM); | |
207 | OPAL_CALL(opal_write_nvram, OPAL_WRITE_NVRAM); | |
208 | OPAL_CALL(opal_handle_interrupt, OPAL_HANDLE_INTERRUPT); | |
209 | OPAL_CALL(opal_poll_events, OPAL_POLL_EVENTS); | |
210 | OPAL_CALL(opal_pci_set_hub_tce_memory, OPAL_PCI_SET_HUB_TCE_MEMORY); | |
211 | OPAL_CALL(opal_pci_set_phb_tce_memory, OPAL_PCI_SET_PHB_TCE_MEMORY); | |
212 | OPAL_CALL(opal_pci_config_read_byte, OPAL_PCI_CONFIG_READ_BYTE); | |
213 | OPAL_CALL(opal_pci_config_read_half_word, OPAL_PCI_CONFIG_READ_HALF_WORD); | |
214 | OPAL_CALL(opal_pci_config_read_word, OPAL_PCI_CONFIG_READ_WORD); | |
215 | OPAL_CALL(opal_pci_config_write_byte, OPAL_PCI_CONFIG_WRITE_BYTE); | |
216 | OPAL_CALL(opal_pci_config_write_half_word, OPAL_PCI_CONFIG_WRITE_HALF_WORD); | |
217 | OPAL_CALL(opal_pci_config_write_word, OPAL_PCI_CONFIG_WRITE_WORD); | |
218 | OPAL_CALL(opal_set_xive, OPAL_SET_XIVE); | |
219 | OPAL_CALL(opal_get_xive, OPAL_GET_XIVE); | |
220 | OPAL_CALL(opal_register_exception_handler, OPAL_REGISTER_OPAL_EXCEPTION_HANDLER); | |
221 | OPAL_CALL(opal_pci_eeh_freeze_status, OPAL_PCI_EEH_FREEZE_STATUS); | |
222 | OPAL_CALL(opal_pci_eeh_freeze_clear, OPAL_PCI_EEH_FREEZE_CLEAR); | |
5ca27efb | 223 | OPAL_CALL(opal_pci_eeh_freeze_set, OPAL_PCI_EEH_FREEZE_SET); |
5b642340 | 224 | OPAL_CALL(opal_pci_err_inject, OPAL_PCI_ERR_INJECT); |
14a43e69 BH |
225 | OPAL_CALL(opal_pci_shpc, OPAL_PCI_SHPC); |
226 | OPAL_CALL(opal_pci_phb_mmio_enable, OPAL_PCI_PHB_MMIO_ENABLE); | |
227 | OPAL_CALL(opal_pci_set_phb_mem_window, OPAL_PCI_SET_PHB_MEM_WINDOW); | |
228 | OPAL_CALL(opal_pci_map_pe_mmio_window, OPAL_PCI_MAP_PE_MMIO_WINDOW); | |
229 | OPAL_CALL(opal_pci_set_phb_table_memory, OPAL_PCI_SET_PHB_TABLE_MEMORY); | |
230 | OPAL_CALL(opal_pci_set_pe, OPAL_PCI_SET_PE); | |
231 | OPAL_CALL(opal_pci_set_peltv, OPAL_PCI_SET_PELTV); | |
232 | OPAL_CALL(opal_pci_set_mve, OPAL_PCI_SET_MVE); | |
233 | OPAL_CALL(opal_pci_set_mve_enable, OPAL_PCI_SET_MVE_ENABLE); | |
234 | OPAL_CALL(opal_pci_get_xive_reissue, OPAL_PCI_GET_XIVE_REISSUE); | |
235 | OPAL_CALL(opal_pci_set_xive_reissue, OPAL_PCI_SET_XIVE_REISSUE); | |
236 | OPAL_CALL(opal_pci_set_xive_pe, OPAL_PCI_SET_XIVE_PE); | |
237 | OPAL_CALL(opal_get_xive_source, OPAL_GET_XIVE_SOURCE); | |
238 | OPAL_CALL(opal_get_msi_32, OPAL_GET_MSI_32); | |
239 | OPAL_CALL(opal_get_msi_64, OPAL_GET_MSI_64); | |
240 | OPAL_CALL(opal_start_cpu, OPAL_START_CPU); | |
241 | OPAL_CALL(opal_query_cpu_status, OPAL_QUERY_CPU_STATUS); | |
242 | OPAL_CALL(opal_write_oppanel, OPAL_WRITE_OPPANEL); | |
243 | OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); | |
244 | OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); | |
245 | OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); | |
f11fe552 BH |
246 | OPAL_CALL(opal_pci_get_hub_diag_data, OPAL_PCI_GET_HUB_DIAG_DATA); |
247 | OPAL_CALL(opal_pci_get_phb_diag_data, OPAL_PCI_GET_PHB_DIAG_DATA); | |
248 | OPAL_CALL(opal_pci_fence_phb, OPAL_PCI_FENCE_PHB); | |
249 | OPAL_CALL(opal_pci_reinit, OPAL_PCI_REINIT); | |
250 | OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR); | |
251 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); | |
252 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); | |
253 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); | |
23773230 GS |
254 | OPAL_CALL(opal_pci_next_error, OPAL_PCI_NEXT_ERROR); |
255 | OPAL_CALL(opal_pci_poll, OPAL_PCI_POLL); | |
137436c9 | 256 | OPAL_CALL(opal_pci_msi_eoi, OPAL_PCI_MSI_EOI); |
23773230 | 257 | OPAL_CALL(opal_pci_get_phb_diag_data2, OPAL_PCI_GET_PHB_DIAG_DATA2); |
cc0efb57 BH |
258 | OPAL_CALL(opal_xscom_read, OPAL_XSCOM_READ); |
259 | OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE); | |
260 | OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); | |
261 | OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); | |
13906db6 | 262 | OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); |
4926616c | 263 | OPAL_CALL(opal_reinit_cpus, OPAL_REINIT_CPUS); |
774fea1a SS |
264 | OPAL_CALL(opal_read_elog, OPAL_ELOG_READ); |
265 | OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK); | |
266 | OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE); | |
267 | OPAL_CALL(opal_resend_pending_logs, OPAL_ELOG_RESEND); | |
268 | OPAL_CALL(opal_write_elog, OPAL_ELOG_WRITE); | |
50bd6153 VH |
269 | OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE); |
270 | OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE); | |
271 | OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); | |
97eb001f | 272 | OPAL_CALL(opal_resync_timebase, OPAL_RESYNC_TIMEBASE); |
bffe6bda | 273 | OPAL_CALL(opal_check_token, OPAL_CHECK_TOKEN); |
c7e64b9c SS |
274 | OPAL_CALL(opal_dump_init, OPAL_DUMP_INIT); |
275 | OPAL_CALL(opal_dump_info, OPAL_DUMP_INFO); | |
276 | OPAL_CALL(opal_dump_info2, OPAL_DUMP_INFO2); | |
277 | OPAL_CALL(opal_dump_read, OPAL_DUMP_READ); | |
278 | OPAL_CALL(opal_dump_ack, OPAL_DUMP_ACK); | |
24366360 MS |
279 | OPAL_CALL(opal_get_msg, OPAL_GET_MSG); |
280 | OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION); | |
c7e64b9c | 281 | OPAL_CALL(opal_dump_resend_notification, OPAL_DUMP_RESEND); |
f7d98d18 | 282 | OPAL_CALL(opal_sync_host_reboot, OPAL_SYNC_HOST_REBOOT); |
7224adbb | 283 | OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ); |
4029cd66 NG |
284 | OPAL_CALL(opal_get_param, OPAL_GET_PARAM); |
285 | OPAL_CALL(opal_set_param, OPAL_SET_PARAM); | |
0ef95b41 | 286 | OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); |
b09c2ec4 VH |
287 | OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); |
288 | OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); | |
09521736 | 289 | OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CXL_MODE); |
16b1d26e NG |
290 | OPAL_CALL(opal_tpo_write, OPAL_WRITE_TPO); |
291 | OPAL_CALL(opal_tpo_read, OPAL_READ_TPO); | |
608b286d JK |
292 | OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND); |
293 | OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV); | |
47083450 | 294 | OPAL_CALL(opal_i2c_request, OPAL_I2C_REQUEST); |