diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2016-07-08 02:37:11 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-07-17 02:42:46 -0400 |
commit | 69c592ed40d32b4b680fd46c1b059cfe8abeb755 (patch) | |
tree | fbe635a6be414b868fc22704afc9a930bb3fa79e | |
parent | b7d6bf4fdd47b7a067e6caecb606e27fd09d1ae9 (diff) |
powerpc/opal: Add real mode call wrappers
Replace the old generic opal_call_realmode() with proper per-call
wrappers similar to the normal ones and convert callers.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/include/asm/opal-api.h | 10 | ||||
-rw-r--r-- | arch/powerpc/include/asm/opal.h | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle_book3s.S | 16 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-wrappers.S | 63 |
4 files changed, 51 insertions, 44 deletions
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index b349621da6ce..0e2e57bcab50 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h | |||
@@ -166,7 +166,8 @@ | |||
166 | #define OPAL_INT_SET_CPPR 123 | 166 | #define OPAL_INT_SET_CPPR 123 |
167 | #define OPAL_INT_EOI 124 | 167 | #define OPAL_INT_EOI 124 |
168 | #define OPAL_INT_SET_MFRR 125 | 168 | #define OPAL_INT_SET_MFRR 125 |
169 | #define OPAL_LAST 125 | 169 | #define OPAL_PCI_TCE_KILL 126 |
170 | #define OPAL_LAST 126 | ||
170 | 171 | ||
171 | /* Device tree flags */ | 172 | /* Device tree flags */ |
172 | 173 | ||
@@ -919,6 +920,13 @@ enum { | |||
919 | OPAL_REBOOT_PLATFORM_ERROR = 1, | 920 | OPAL_REBOOT_PLATFORM_ERROR = 1, |
920 | }; | 921 | }; |
921 | 922 | ||
923 | /* Argument to OPAL_PCI_TCE_KILL */ | ||
924 | enum { | ||
925 | OPAL_PCI_TCE_KILL_PAGES, | ||
926 | OPAL_PCI_TCE_KILL_PE, | ||
927 | OPAL_PCI_TCE_KILL_ALL, | ||
928 | }; | ||
929 | |||
922 | #endif /* __ASSEMBLY__ */ | 930 | #endif /* __ASSEMBLY__ */ |
923 | 931 | ||
924 | #endif /* __OPAL_API_H */ | 932 | #endif /* __OPAL_API_H */ |
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 162ebe6f2de6..b656bb192b63 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -222,6 +222,12 @@ int64_t opal_int_get_xirr(uint32_t *out_xirr, bool just_poll); | |||
222 | int64_t opal_int_set_cppr(uint8_t cppr); | 222 | int64_t opal_int_set_cppr(uint8_t cppr); |
223 | int64_t opal_int_eoi(uint32_t xirr); | 223 | int64_t opal_int_eoi(uint32_t xirr); |
224 | int64_t opal_int_set_mfrr(uint32_t cpu, uint8_t mfrr); | 224 | int64_t opal_int_set_mfrr(uint32_t cpu, uint8_t mfrr); |
225 | int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, | ||
226 | uint32_t pe_num, uint32_t tce_size, | ||
227 | uint64_t dma_addr, uint32_t npages); | ||
228 | int64_t opal_rm_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, | ||
229 | uint32_t pe_num, uint32_t tce_size, | ||
230 | uint64_t dma_addr, uint32_t npages); | ||
225 | 231 | ||
226 | /* Internal functions */ | 232 | /* Internal functions */ |
227 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, | 233 | extern int early_init_dt_scan_opal(unsigned long node, const char *uname, |
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 1f564eb409c3..335eb6cedae5 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S | |||
@@ -245,8 +245,7 @@ fastsleep_workaround_at_entry: | |||
245 | /* Fast sleep workaround */ | 245 | /* Fast sleep workaround */ |
246 | li r3,1 | 246 | li r3,1 |
247 | li r4,1 | 247 | li r4,1 |
248 | li r0,OPAL_CONFIG_CPU_IDLE_STATE | 248 | bl opal_rm_config_cpu_idle_state |
249 | bl opal_call_realmode | ||
250 | 249 | ||
251 | /* Clear Lock bit */ | 250 | /* Clear Lock bit */ |
252 | li r0,0 | 251 | li r0,0 |
@@ -337,8 +336,7 @@ ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_ARCH_207S, 66); \ | |||
337 | ld r2,PACATOC(r13); \ | 336 | ld r2,PACATOC(r13); \ |
338 | ld r1,PACAR1(r13); \ | 337 | ld r1,PACAR1(r13); \ |
339 | std r3,ORIG_GPR3(r1); /* Save original r3 */ \ | 338 | std r3,ORIG_GPR3(r1); /* Save original r3 */ \ |
340 | li r0,OPAL_HANDLE_HMI; /* Pass opal token argument*/ \ | 339 | bl opal_rm_handle_hmi; \ |
341 | bl opal_call_realmode; \ | ||
342 | ld r3,ORIG_GPR3(r1); /* Restore original r3 */ \ | 340 | ld r3,ORIG_GPR3(r1); /* Restore original r3 */ \ |
343 | 20: nop; | 341 | 20: nop; |
344 | 342 | ||
@@ -430,7 +428,7 @@ _GLOBAL(pnv_wakeup_tb_loss) | |||
430 | * until they are restored, they are free to be used. | 428 | * until they are restored, they are free to be used. |
431 | * | 429 | * |
432 | * Save SRR1 and LR in NVGPRs as they might be clobbered in | 430 | * Save SRR1 and LR in NVGPRs as they might be clobbered in |
433 | * opal_call_realmode (called in CHECK_HMI_INTERRUPT). SRR1 is required | 431 | * opal_call() (called in CHECK_HMI_INTERRUPT). SRR1 is required |
434 | * to determine the wakeup reason if we branch to kvm_start_guest. LR | 432 | * to determine the wakeup reason if we branch to kvm_start_guest. LR |
435 | * is required to return back to reset vector after hypervisor state | 433 | * is required to return back to reset vector after hypervisor state |
436 | * restore is complete. | 434 | * restore is complete. |
@@ -530,10 +528,7 @@ timebase_resync: | |||
530 | */ | 528 | */ |
531 | ble cr3,clear_lock | 529 | ble cr3,clear_lock |
532 | /* Time base re-sync */ | 530 | /* Time base re-sync */ |
533 | li r0,OPAL_RESYNC_TIMEBASE | 531 | bl opal_rm_resync_timebase; |
534 | bl opal_call_realmode; | ||
535 | /* TODO: Check r3 for failure */ | ||
536 | |||
537 | /* | 532 | /* |
538 | * If waking up from sleep, per core state is not lost, skip to | 533 | * If waking up from sleep, per core state is not lost, skip to |
539 | * clear_lock. | 534 | * clear_lock. |
@@ -622,8 +617,7 @@ hypervisor_state_restored: | |||
622 | fastsleep_workaround_at_exit: | 617 | fastsleep_workaround_at_exit: |
623 | li r3,1 | 618 | li r3,1 |
624 | li r4,0 | 619 | li r4,0 |
625 | li r0,OPAL_CONFIG_CPU_IDLE_STATE | 620 | bl opal_rm_config_cpu_idle_state |
626 | bl opal_call_realmode | ||
627 | b timebase_resync | 621 | b timebase_resync |
628 | 622 | ||
629 | /* | 623 | /* |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index c7764f9f661d..cf928bba4d9a 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -59,7 +59,7 @@ END_FTR_SECTION(0, 1); \ | |||
59 | #define OPAL_CALL(name, token) \ | 59 | #define OPAL_CALL(name, token) \ |
60 | _GLOBAL_TOC(name); \ | 60 | _GLOBAL_TOC(name); \ |
61 | mflr r0; \ | 61 | mflr r0; \ |
62 | std r0,16(r1); \ | 62 | std r0,PPC_LR_STKOFF(r1); \ |
63 | li r0,token; \ | 63 | li r0,token; \ |
64 | OPAL_BRANCH(opal_tracepoint_entry) \ | 64 | OPAL_BRANCH(opal_tracepoint_entry) \ |
65 | mfcr r12; \ | 65 | mfcr r12; \ |
@@ -92,7 +92,7 @@ opal_return: | |||
92 | FIXUP_ENDIAN | 92 | FIXUP_ENDIAN |
93 | ld r2,PACATOC(r13); | 93 | ld r2,PACATOC(r13); |
94 | lwz r4,8(r1); | 94 | lwz r4,8(r1); |
95 | ld r5,16(r1); | 95 | ld r5,PPC_LR_STKOFF(r1); |
96 | ld r6,PACASAVEDMSR(r13); | 96 | ld r6,PACASAVEDMSR(r13); |
97 | mtspr SPRN_SRR0,r5; | 97 | mtspr SPRN_SRR0,r5; |
98 | mtspr SPRN_SRR1,r6; | 98 | mtspr SPRN_SRR1,r6; |
@@ -157,43 +157,37 @@ opal_tracepoint_return: | |||
157 | blr | 157 | blr |
158 | #endif | 158 | #endif |
159 | 159 | ||
160 | /* | 160 | #define OPAL_CALL_REAL(name, token) \ |
161 | * Make opal call in realmode. This is a generic function to be called | 161 | _GLOBAL_TOC(name); \ |
162 | * from realmode. It handles endianness. | 162 | mflr r0; \ |
163 | * | 163 | std r0,PPC_LR_STKOFF(r1); \ |
164 | * r13 - paca pointer | 164 | li r0,token; \ |
165 | * r1 - stack pointer | 165 | mfcr r12; \ |
166 | * r0 - opal token | 166 | stw r12,8(r1); \ |
167 | */ | 167 | \ |
168 | _GLOBAL(opal_call_realmode) | 168 | /* Set opal return address */ \ |
169 | mflr r12 | 169 | LOAD_REG_ADDR(r11, opal_return_realmode); \ |
170 | std r12,PPC_LR_STKOFF(r1) | 170 | mtlr r11; \ |
171 | ld r2,PACATOC(r13) | 171 | mfmsr r12; \ |
172 | /* Set opal return address */ | 172 | li r11,MSR_LE; \ |
173 | LOAD_REG_ADDR(r12,return_from_opal_call) | 173 | andc r12,r12,r11; \ |
174 | mtlr r12 | 174 | mtspr SPRN_HSRR1,r12; \ |
175 | 175 | LOAD_REG_ADDR(r11,opal); \ | |
176 | mfmsr r12 | 176 | ld r12,8(r11); \ |
177 | #ifdef __LITTLE_ENDIAN__ | 177 | ld r2,0(r11); \ |
178 | /* Handle endian-ness */ | 178 | mtspr SPRN_HSRR0,r12; \ |
179 | li r11,MSR_LE | ||
180 | andc r12,r12,r11 | ||
181 | #endif | ||
182 | mtspr SPRN_HSRR1,r12 | ||
183 | LOAD_REG_ADDR(r11,opal) | ||
184 | ld r12,8(r11) | ||
185 | ld r2,0(r11) | ||
186 | mtspr SPRN_HSRR0,r12 | ||
187 | hrfid | 179 | hrfid |
188 | 180 | ||
189 | return_from_opal_call: | 181 | opal_return_realmode: |
190 | #ifdef __LITTLE_ENDIAN__ | ||
191 | FIXUP_ENDIAN | 182 | FIXUP_ENDIAN |
192 | #endif | 183 | ld r2,PACATOC(r13); |
184 | lwz r11,8(r1); | ||
193 | ld r12,PPC_LR_STKOFF(r1) | 185 | ld r12,PPC_LR_STKOFF(r1) |
186 | mtcr r11; | ||
194 | mtlr r12 | 187 | mtlr r12 |
195 | blr | 188 | blr |
196 | 189 | ||
190 | |||
197 | OPAL_CALL(opal_invalid_call, OPAL_INVALID_CALL); | 191 | OPAL_CALL(opal_invalid_call, OPAL_INVALID_CALL); |
198 | OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE); | 192 | OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE); |
199 | OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ); | 193 | OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ); |
@@ -271,6 +265,7 @@ OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE); | |||
271 | OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE); | 265 | OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE); |
272 | OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); | 266 | OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE); |
273 | OPAL_CALL(opal_resync_timebase, OPAL_RESYNC_TIMEBASE); | 267 | OPAL_CALL(opal_resync_timebase, OPAL_RESYNC_TIMEBASE); |
268 | OPAL_CALL_REAL(opal_rm_resync_timebase, OPAL_RESYNC_TIMEBASE); | ||
274 | OPAL_CALL(opal_check_token, OPAL_CHECK_TOKEN); | 269 | OPAL_CALL(opal_check_token, OPAL_CHECK_TOKEN); |
275 | OPAL_CALL(opal_dump_init, OPAL_DUMP_INIT); | 270 | OPAL_CALL(opal_dump_init, OPAL_DUMP_INIT); |
276 | OPAL_CALL(opal_dump_info, OPAL_DUMP_INFO); | 271 | OPAL_CALL(opal_dump_info, OPAL_DUMP_INFO); |
@@ -286,7 +281,9 @@ OPAL_CALL(opal_sensor_read, OPAL_SENSOR_READ); | |||
286 | OPAL_CALL(opal_get_param, OPAL_GET_PARAM); | 281 | OPAL_CALL(opal_get_param, OPAL_GET_PARAM); |
287 | OPAL_CALL(opal_set_param, OPAL_SET_PARAM); | 282 | OPAL_CALL(opal_set_param, OPAL_SET_PARAM); |
288 | OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); | 283 | OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); |
284 | OPAL_CALL_REAL(opal_rm_handle_hmi, OPAL_HANDLE_HMI); | ||
289 | OPAL_CALL(opal_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE); | 285 | OPAL_CALL(opal_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE); |
286 | OPAL_CALL_REAL(opal_rm_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE); | ||
290 | OPAL_CALL(opal_slw_set_reg, OPAL_SLW_SET_REG); | 287 | OPAL_CALL(opal_slw_set_reg, OPAL_SLW_SET_REG); |
291 | OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); | 288 | OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); |
292 | OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); | 289 | OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); |
@@ -311,3 +308,5 @@ OPAL_CALL(opal_int_get_xirr, OPAL_INT_GET_XIRR); | |||
311 | OPAL_CALL(opal_int_set_cppr, OPAL_INT_SET_CPPR); | 308 | OPAL_CALL(opal_int_set_cppr, OPAL_INT_SET_CPPR); |
312 | OPAL_CALL(opal_int_eoi, OPAL_INT_EOI); | 309 | OPAL_CALL(opal_int_eoi, OPAL_INT_EOI); |
313 | OPAL_CALL(opal_int_set_mfrr, OPAL_INT_SET_MFRR); | 310 | OPAL_CALL(opal_int_set_mfrr, OPAL_INT_SET_MFRR); |
311 | OPAL_CALL(opal_pci_tce_kill, OPAL_PCI_TCE_KILL); | ||
312 | OPAL_CALL_REAL(opal_rm_pci_tce_kill, OPAL_PCI_TCE_KILL); | ||