Commit | Line | Data |
---|---|---|
75d9fc7f NP |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/percpu.h> | |
3 | #include <linux/jump_label.h> | |
4 | #include <asm/opal-api.h> | |
5 | #include <asm/trace.h> | |
6 | #include <asm/asm-prototypes.h> | |
7 | ||
8 | #ifdef CONFIG_TRACEPOINTS | |
9 | /* | |
10 | * Since the tracing code might execute OPAL calls we need to guard against | |
11 | * recursion. | |
12 | */ | |
13 | static DEFINE_PER_CPU(unsigned int, opal_trace_depth); | |
14 | ||
15 | static void __trace_opal_entry(s64 a0, s64 a1, s64 a2, s64 a3, | |
16 | s64 a4, s64 a5, s64 a6, s64 a7, | |
17 | unsigned long opcode) | |
18 | { | |
19 | unsigned int *depth; | |
20 | unsigned long args[8]; | |
21 | ||
22 | depth = this_cpu_ptr(&opal_trace_depth); | |
23 | ||
24 | if (*depth) | |
25 | return; | |
26 | ||
27 | args[0] = a0; | |
28 | args[1] = a1; | |
29 | args[2] = a2; | |
30 | args[3] = a3; | |
31 | args[4] = a4; | |
32 | args[5] = a5; | |
33 | args[6] = a6; | |
34 | args[7] = a7; | |
35 | ||
36 | (*depth)++; | |
37 | trace_opal_entry(opcode, &args[0]); | |
38 | (*depth)--; | |
39 | } | |
40 | ||
41 | static void __trace_opal_exit(unsigned long opcode, unsigned long retval) | |
42 | { | |
43 | unsigned int *depth; | |
44 | ||
45 | depth = this_cpu_ptr(&opal_trace_depth); | |
46 | ||
47 | if (*depth) | |
48 | return; | |
49 | ||
50 | (*depth)++; | |
51 | trace_opal_exit(opcode, retval); | |
52 | (*depth)--; | |
53 | } | |
54 | ||
55 | static DEFINE_STATIC_KEY_FALSE(opal_tracepoint_key); | |
56 | ||
57 | int opal_tracepoint_regfunc(void) | |
58 | { | |
59 | static_branch_inc(&opal_tracepoint_key); | |
60 | return 0; | |
61 | } | |
62 | ||
63 | void opal_tracepoint_unregfunc(void) | |
64 | { | |
65 | static_branch_dec(&opal_tracepoint_key); | |
66 | } | |
67 | ||
68 | static s64 __opal_call_trace(s64 a0, s64 a1, s64 a2, s64 a3, | |
69 | s64 a4, s64 a5, s64 a6, s64 a7, | |
70 | unsigned long opcode, unsigned long msr) | |
71 | { | |
72 | s64 ret; | |
73 | ||
74 | __trace_opal_entry(a0, a1, a2, a3, a4, a5, a6, a7, opcode); | |
75 | ret = __opal_call(a0, a1, a2, a3, a4, a5, a6, a7, opcode, msr); | |
76 | __trace_opal_exit(opcode, ret); | |
77 | ||
78 | return ret; | |
79 | } | |
80 | ||
81 | #define DO_TRACE (static_branch_unlikely(&opal_tracepoint_key)) | |
82 | ||
83 | #else /* CONFIG_TRACEPOINTS */ | |
84 | ||
85 | static s64 __opal_call_trace(s64 a0, s64 a1, s64 a2, s64 a3, | |
86 | s64 a4, s64 a5, s64 a6, s64 a7, | |
87 | unsigned long opcode, unsigned long msr) | |
88 | { | |
89 | } | |
90 | ||
91 | #define DO_TRACE false | |
92 | #endif /* CONFIG_TRACEPOINTS */ | |
93 | ||
94 | static int64_t opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3, | |
95 | int64_t a4, int64_t a5, int64_t a6, int64_t a7, int64_t opcode) | |
96 | { | |
97 | unsigned long flags; | |
98 | unsigned long msr = mfmsr(); | |
99 | bool mmu = (msr & (MSR_IR|MSR_DR)); | |
100 | int64_t ret; | |
101 | ||
102 | msr &= ~MSR_EE; | |
103 | ||
104 | if (unlikely(!mmu)) | |
105 | return __opal_call(a0, a1, a2, a3, a4, a5, a6, a7, opcode, msr); | |
106 | ||
107 | local_save_flags(flags); | |
108 | hard_irq_disable(); | |
109 | ||
110 | if (DO_TRACE) { | |
111 | ret = __opal_call_trace(a0, a1, a2, a3, a4, a5, a6, a7, opcode, msr); | |
112 | } else { | |
113 | ret = __opal_call(a0, a1, a2, a3, a4, a5, a6, a7, opcode, msr); | |
114 | } | |
115 | ||
116 | local_irq_restore(flags); | |
117 | ||
118 | return ret; | |
119 | } | |
120 | ||
121 | #define OPAL_CALL(name, opcode) \ | |
122 | int64_t name(int64_t a0, int64_t a1, int64_t a2, int64_t a3, \ | |
123 | int64_t a4, int64_t a5, int64_t a6, int64_t a7) \ | |
124 | { \ | |
125 | return opal_call(a0, a1, a2, a3, a4, a5, a6, a7, opcode); \ | |
126 | } | |
127 | ||
128 | OPAL_CALL(opal_invalid_call, OPAL_INVALID_CALL); | |
129 | OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE); | |
130 | OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ); | |
131 | OPAL_CALL(opal_console_write_buffer_space, OPAL_CONSOLE_WRITE_BUFFER_SPACE); | |
132 | OPAL_CALL(opal_rtc_read, OPAL_RTC_READ); | |
133 | OPAL_CALL(opal_rtc_write, OPAL_RTC_WRITE); | |
134 | OPAL_CALL(opal_cec_power_down, OPAL_CEC_POWER_DOWN); | |
135 | OPAL_CALL(opal_cec_reboot, OPAL_CEC_REBOOT); | |
136 | OPAL_CALL(opal_cec_reboot2, OPAL_CEC_REBOOT2); | |
137 | OPAL_CALL(opal_read_nvram, OPAL_READ_NVRAM); | |
138 | OPAL_CALL(opal_write_nvram, OPAL_WRITE_NVRAM); | |
139 | OPAL_CALL(opal_handle_interrupt, OPAL_HANDLE_INTERRUPT); | |
140 | OPAL_CALL(opal_poll_events, OPAL_POLL_EVENTS); | |
141 | OPAL_CALL(opal_pci_set_hub_tce_memory, OPAL_PCI_SET_HUB_TCE_MEMORY); | |
142 | OPAL_CALL(opal_pci_set_phb_tce_memory, OPAL_PCI_SET_PHB_TCE_MEMORY); | |
143 | OPAL_CALL(opal_pci_config_read_byte, OPAL_PCI_CONFIG_READ_BYTE); | |
144 | OPAL_CALL(opal_pci_config_read_half_word, OPAL_PCI_CONFIG_READ_HALF_WORD); | |
145 | OPAL_CALL(opal_pci_config_read_word, OPAL_PCI_CONFIG_READ_WORD); | |
146 | OPAL_CALL(opal_pci_config_write_byte, OPAL_PCI_CONFIG_WRITE_BYTE); | |
147 | OPAL_CALL(opal_pci_config_write_half_word, OPAL_PCI_CONFIG_WRITE_HALF_WORD); | |
148 | OPAL_CALL(opal_pci_config_write_word, OPAL_PCI_CONFIG_WRITE_WORD); | |
149 | OPAL_CALL(opal_set_xive, OPAL_SET_XIVE); | |
150 | OPAL_CALL(opal_get_xive, OPAL_GET_XIVE); | |
151 | OPAL_CALL(opal_register_exception_handler, OPAL_REGISTER_OPAL_EXCEPTION_HANDLER); | |
152 | OPAL_CALL(opal_pci_eeh_freeze_status, OPAL_PCI_EEH_FREEZE_STATUS); | |
153 | OPAL_CALL(opal_pci_eeh_freeze_clear, OPAL_PCI_EEH_FREEZE_CLEAR); | |
154 | OPAL_CALL(opal_pci_eeh_freeze_set, OPAL_PCI_EEH_FREEZE_SET); | |
155 | OPAL_CALL(opal_pci_err_inject, OPAL_PCI_ERR_INJECT); | |
156 | OPAL_CALL(opal_pci_shpc, OPAL_PCI_SHPC); | |
157 | OPAL_CALL(opal_pci_phb_mmio_enable, OPAL_PCI_PHB_MMIO_ENABLE); | |
158 | OPAL_CALL(opal_pci_set_phb_mem_window, OPAL_PCI_SET_PHB_MEM_WINDOW); | |
159 | OPAL_CALL(opal_pci_map_pe_mmio_window, OPAL_PCI_MAP_PE_MMIO_WINDOW); | |
160 | OPAL_CALL(opal_pci_set_phb_table_memory, OPAL_PCI_SET_PHB_TABLE_MEMORY); | |
161 | OPAL_CALL(opal_pci_set_pe, OPAL_PCI_SET_PE); | |
162 | OPAL_CALL(opal_pci_set_peltv, OPAL_PCI_SET_PELTV); | |
163 | OPAL_CALL(opal_pci_set_mve, OPAL_PCI_SET_MVE); | |
164 | OPAL_CALL(opal_pci_set_mve_enable, OPAL_PCI_SET_MVE_ENABLE); | |
165 | OPAL_CALL(opal_pci_get_xive_reissue, OPAL_PCI_GET_XIVE_REISSUE); | |
166 | OPAL_CALL(opal_pci_set_xive_reissue, OPAL_PCI_SET_XIVE_REISSUE); | |
167 | OPAL_CALL(opal_pci_set_xive_pe, OPAL_PCI_SET_XIVE_PE); | |
168 | OPAL_CALL(opal_get_xive_source, OPAL_GET_XIVE_SOURCE); | |
169 | OPAL_CALL(opal_get_msi_32, OPAL_GET_MSI_32); | |
170 | OPAL_CALL(opal_get_msi_64, OPAL_GET_MSI_64); | |
171 | OPAL_CALL(opal_start_cpu, OPAL_START_CPU); | |
172 | OPAL_CALL(opal_query_cpu_status, OPAL_QUERY_CPU_STATUS); | |
173 | OPAL_CALL(opal_write_oppanel, OPAL_WRITE_OPPANEL); | |
174 | OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); | |
175 | OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); | |
176 | OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); | |
177 | OPAL_CALL(opal_pci_get_hub_diag_data, OPAL_PCI_GET_HUB_DIAG_DATA); | |
178 | OPAL_CALL(opal_pci_get_phb_diag_data, OPAL_PCI_GET_PHB_DIAG_DATA); | |
179 | OPAL_CALL(opal_pci_fence_phb, OPAL_PCI_FENCE_PHB); | |
180 | OPAL_CALL(opal_pci_reinit, OPAL_PCI_REINIT); | |
181 | OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR); | |
182 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); | |
183 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); | |
184 | OPAL_CALL(opal_get_dpo_status, OPAL_GET_DPO_STATUS); | |
185 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); | |
186 | OPAL_CALL(opal_pci_next_error, OPAL_PCI_NEXT_ERROR); | |
187 | OPAL_CALL(opal_pci_poll, OPAL_PCI_POLL); | |
188 | OPAL_CALL(opal_pci_msi_eoi, OPAL_PCI_MSI_EOI); | |
189 | OPAL_CALL(opal_pci_get_phb_diag_data2, OPAL_PCI_GET_PHB_DIAG_DATA2); | |
190 | OPAL_CALL(opal_xscom_read, OPAL_XSCOM_READ); | |
191 | OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE); | |
192 | OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); | |
193 | OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); | |
194 | OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); | |
195 | OPAL_CALL(opal_reinit_cpus, OPAL_REINIT_CPUS); | |
196 | OPAL_CALL(opal_read_elog, OPAL_ELOG_READ); | |
197 | OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK); | |
198 | OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE); | |
199 | OPAL_CALL(opal_resend_pending_logs, OPAL_ELOG_RESEND); | |
200 | OPAL_CALL(opal_write_elog, OPAL_ELOG_WRITE); | |
201 | OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE); | |
202 | OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE); | |
203 | OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); | |
204 | OPAL_CALL(opal_resync_timebase, OPAL_RESYNC_TIMEBASE); | |
205 | OPAL_CALL(opal_check_token, OPAL_CHECK_TOKEN); | |
206 | OPAL_CALL(opal_dump_init, OPAL_DUMP_INIT); | |
207 | OPAL_CALL(opal_dump_info, OPAL_DUMP_INFO); | |
208 | OPAL_CALL(opal_dump_info2, OPAL_DUMP_INFO2); | |
209 | OPAL_CALL(opal_dump_read, OPAL_DUMP_READ); | |
210 | OPAL_CALL(opal_dump_ack, OPAL_DUMP_ACK); | |
211 | OPAL_CALL(opal_get_msg, OPAL_GET_MSG); | |
212 | OPAL_CALL(opal_write_oppanel_async, OPAL_WRITE_OPPANEL_ASYNC); | |
213 | OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION); | |
214 | OPAL_CALL(opal_dump_resend_notification, OPAL_DUMP_RESEND); | |
215 | OPAL_CALL(opal_sync_host_reboot, OPAL_SYNC_HOST_REBOOT); | |
216 | OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ); | |
217 | OPAL_CALL(opal_get_param, OPAL_GET_PARAM); | |
218 | OPAL_CALL(opal_set_param, OPAL_SET_PARAM); | |
219 | OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); | |
220 | OPAL_CALL(opal_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE); | |
221 | OPAL_CALL(opal_slw_set_reg, OPAL_SLW_SET_REG); | |
222 | OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); | |
223 | OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); | |
224 | OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CAPI_MODE); | |
225 | OPAL_CALL(opal_tpo_write, OPAL_WRITE_TPO); | |
226 | OPAL_CALL(opal_tpo_read, OPAL_READ_TPO); | |
227 | OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND); | |
228 | OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV); | |
229 | OPAL_CALL(opal_i2c_request, OPAL_I2C_REQUEST); | |
230 | OPAL_CALL(opal_flash_read, OPAL_FLASH_READ); | |
231 | OPAL_CALL(opal_flash_write, OPAL_FLASH_WRITE); | |
232 | OPAL_CALL(opal_flash_erase, OPAL_FLASH_ERASE); | |
233 | OPAL_CALL(opal_prd_msg, OPAL_PRD_MSG); | |
234 | OPAL_CALL(opal_leds_get_ind, OPAL_LEDS_GET_INDICATOR); | |
235 | OPAL_CALL(opal_leds_set_ind, OPAL_LEDS_SET_INDICATOR); | |
236 | OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH); | |
237 | OPAL_CALL(opal_get_device_tree, OPAL_GET_DEVICE_TREE); | |
238 | OPAL_CALL(opal_pci_get_presence_state, OPAL_PCI_GET_PRESENCE_STATE); | |
239 | OPAL_CALL(opal_pci_get_power_state, OPAL_PCI_GET_POWER_STATE); | |
240 | OPAL_CALL(opal_pci_set_power_state, OPAL_PCI_SET_POWER_STATE); | |
241 | OPAL_CALL(opal_int_get_xirr, OPAL_INT_GET_XIRR); | |
242 | OPAL_CALL(opal_int_set_cppr, OPAL_INT_SET_CPPR); | |
243 | OPAL_CALL(opal_int_eoi, OPAL_INT_EOI); | |
244 | OPAL_CALL(opal_int_set_mfrr, OPAL_INT_SET_MFRR); | |
245 | OPAL_CALL(opal_pci_tce_kill, OPAL_PCI_TCE_KILL); | |
246 | OPAL_CALL(opal_nmmu_set_ptcr, OPAL_NMMU_SET_PTCR); | |
247 | OPAL_CALL(opal_xive_reset, OPAL_XIVE_RESET); | |
248 | OPAL_CALL(opal_xive_get_irq_info, OPAL_XIVE_GET_IRQ_INFO); | |
249 | OPAL_CALL(opal_xive_get_irq_config, OPAL_XIVE_GET_IRQ_CONFIG); | |
250 | OPAL_CALL(opal_xive_set_irq_config, OPAL_XIVE_SET_IRQ_CONFIG); | |
251 | OPAL_CALL(opal_xive_get_queue_info, OPAL_XIVE_GET_QUEUE_INFO); | |
252 | OPAL_CALL(opal_xive_set_queue_info, OPAL_XIVE_SET_QUEUE_INFO); | |
253 | OPAL_CALL(opal_xive_donate_page, OPAL_XIVE_DONATE_PAGE); | |
254 | OPAL_CALL(opal_xive_alloc_vp_block, OPAL_XIVE_ALLOCATE_VP_BLOCK); | |
255 | OPAL_CALL(opal_xive_free_vp_block, OPAL_XIVE_FREE_VP_BLOCK); | |
256 | OPAL_CALL(opal_xive_allocate_irq, OPAL_XIVE_ALLOCATE_IRQ); | |
257 | OPAL_CALL(opal_xive_free_irq, OPAL_XIVE_FREE_IRQ); | |
258 | OPAL_CALL(opal_xive_get_vp_info, OPAL_XIVE_GET_VP_INFO); | |
259 | OPAL_CALL(opal_xive_set_vp_info, OPAL_XIVE_SET_VP_INFO); | |
260 | OPAL_CALL(opal_xive_sync, OPAL_XIVE_SYNC); | |
261 | OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP); | |
262 | OPAL_CALL(opal_signal_system_reset, OPAL_SIGNAL_SYSTEM_RESET); | |
263 | OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT); | |
264 | OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT); | |
265 | OPAL_CALL(opal_npu_map_lpar, OPAL_NPU_MAP_LPAR); | |
266 | OPAL_CALL(opal_imc_counters_init, OPAL_IMC_COUNTERS_INIT); | |
267 | OPAL_CALL(opal_imc_counters_start, OPAL_IMC_COUNTERS_START); | |
268 | OPAL_CALL(opal_imc_counters_stop, OPAL_IMC_COUNTERS_STOP); | |
269 | OPAL_CALL(opal_pci_set_p2p, OPAL_PCI_SET_P2P); | |
270 | OPAL_CALL(opal_get_powercap, OPAL_GET_POWERCAP); | |
271 | OPAL_CALL(opal_set_powercap, OPAL_SET_POWERCAP); | |
272 | OPAL_CALL(opal_get_power_shift_ratio, OPAL_GET_POWER_SHIFT_RATIO); | |
273 | OPAL_CALL(opal_set_power_shift_ratio, OPAL_SET_POWER_SHIFT_RATIO); | |
274 | OPAL_CALL(opal_sensor_group_clear, OPAL_SENSOR_GROUP_CLEAR); | |
275 | OPAL_CALL(opal_quiesce, OPAL_QUIESCE); | |
276 | OPAL_CALL(opal_npu_spa_setup, OPAL_NPU_SPA_SETUP); | |
277 | OPAL_CALL(opal_npu_spa_clear_cache, OPAL_NPU_SPA_CLEAR_CACHE); | |
278 | OPAL_CALL(opal_npu_tl_set, OPAL_NPU_TL_SET); | |
279 | OPAL_CALL(opal_pci_get_pbcq_tunnel_bar, OPAL_PCI_GET_PBCQ_TUNNEL_BAR); | |
280 | OPAL_CALL(opal_pci_set_pbcq_tunnel_bar, OPAL_PCI_SET_PBCQ_TUNNEL_BAR); | |
281 | OPAL_CALL(opal_sensor_read_u64, OPAL_SENSOR_READ_U64); | |
282 | OPAL_CALL(opal_sensor_group_enable, OPAL_SENSOR_GROUP_ENABLE); | |
283 | OPAL_CALL(opal_nx_coproc_init, OPAL_NX_COPROC_INIT); |