Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 2 | * Routines and structures for signalling other processors. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 3 | * |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 4 | * Copyright IBM Corp. 1999,2010 |
| 5 | * Author(s): Denis Joseph Barrow, |
| 6 | * Martin Schwidefsky <schwidefsky@de.ibm.com>, |
| 7 | * Heiko Carstens <heiko.carstens@de.ibm.com>, |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 8 | */ |
| 9 | |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 10 | #ifndef __ASM_SIGP_H |
| 11 | #define __ASM_SIGP_H |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 12 | |
Heiko Carstens | fb380aa | 2010-01-13 20:44:37 +0100 | [diff] [blame] | 13 | #include <asm/system.h> |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 14 | |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 15 | /* Get real cpu address from logical cpu number. */ |
| 16 | extern unsigned short __cpu_logical_map[]; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 | |
Heiko Carstens | fb380aa | 2010-01-13 20:44:37 +0100 | [diff] [blame] | 18 | static inline int cpu_logical_map(int cpu) |
| 19 | { |
| 20 | #ifdef CONFIG_SMP |
| 21 | return __cpu_logical_map[cpu]; |
| 22 | #else |
| 23 | return stap(); |
| 24 | #endif |
| 25 | } |
| 26 | |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 27 | enum { |
Gerald Schaefer | 59b6978 | 2010-02-26 22:37:40 +0100 | [diff] [blame] | 28 | sigp_sense = 1, |
| 29 | sigp_external_call = 2, |
| 30 | sigp_emergency_signal = 3, |
| 31 | sigp_start = 4, |
| 32 | sigp_stop = 5, |
| 33 | sigp_restart = 6, |
| 34 | sigp_stop_and_store_status = 9, |
| 35 | sigp_initial_cpu_reset = 11, |
| 36 | sigp_cpu_reset = 12, |
| 37 | sigp_set_prefix = 13, |
| 38 | sigp_store_status_at_address = 14, |
| 39 | sigp_store_extended_status_at_address = 15, |
| 40 | sigp_set_architecture = 18, |
| 41 | sigp_conditional_emergency_signal = 19, |
| 42 | sigp_sense_running = 21, |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 43 | }; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 | |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 45 | enum { |
Gerald Schaefer | 59b6978 | 2010-02-26 22:37:40 +0100 | [diff] [blame] | 46 | sigp_order_code_accepted = 0, |
| 47 | sigp_status_stored = 1, |
| 48 | sigp_busy = 2, |
| 49 | sigp_not_operational = 3, |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 50 | }; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 51 | |
| 52 | /* |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 53 | * Definitions for external call. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 54 | */ |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 55 | enum { |
| 56 | ec_schedule = 0, |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 57 | ec_call_function, |
Heiko Carstens | ca9fc75 | 2008-12-25 13:38:39 +0100 | [diff] [blame] | 58 | ec_call_function_single, |
Martin Schwidefsky | 85ac7ca | 2011-12-27 11:27:22 +0100 | [diff] [blame] | 59 | ec_stop_cpu, |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 60 | }; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 61 | |
| 62 | /* |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 63 | * Signal processor. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 64 | */ |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 65 | static inline int raw_sigp(u16 cpu, int order) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 66 | { |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 67 | register unsigned long reg1 asm ("1") = 0; |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 68 | int ccode; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 69 | |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 70 | asm volatile( |
| 71 | " sigp %1,%2,0(%3)\n" |
| 72 | " ipm %0\n" |
| 73 | " srl %0,28\n" |
| 74 | : "=d" (ccode) |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 75 | : "d" (reg1), "d" (cpu), |
| 76 | "a" (order) : "cc" , "memory"); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 77 | return ccode; |
| 78 | } |
| 79 | |
| 80 | /* |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 81 | * Signal processor with parameter. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 82 | */ |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 83 | static inline int raw_sigp_p(u32 parameter, u16 cpu, int order) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 84 | { |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 85 | register unsigned int reg1 asm ("1") = parameter; |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 86 | int ccode; |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 87 | |
| 88 | asm volatile( |
| 89 | " sigp %1,%2,0(%3)\n" |
| 90 | " ipm %0\n" |
| 91 | " srl %0,28\n" |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 92 | : "=d" (ccode) |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 93 | : "d" (reg1), "d" (cpu), |
| 94 | "a" (order) : "cc" , "memory"); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 95 | return ccode; |
| 96 | } |
| 97 | |
| 98 | /* |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 99 | * Signal processor with parameter and return status. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 100 | */ |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 101 | static inline int raw_sigp_ps(u32 *status, u32 parm, u16 cpu, int order) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 102 | { |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 103 | register unsigned int reg1 asm ("1") = parm; |
| 104 | int ccode; |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 105 | |
| 106 | asm volatile( |
| 107 | " sigp %1,%2,0(%3)\n" |
| 108 | " ipm %0\n" |
| 109 | " srl %0,28\n" |
| 110 | : "=d" (ccode), "+d" (reg1) |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 111 | : "d" (cpu), "a" (order) |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 112 | : "cc" , "memory"); |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 113 | *status = reg1; |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 114 | return ccode; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 115 | } |
| 116 | |
Heiko Carstens | a93b8ec | 2010-02-26 22:37:35 +0100 | [diff] [blame] | 117 | static inline int sigp(int cpu, int order) |
| 118 | { |
| 119 | return raw_sigp(cpu_logical_map(cpu), order); |
| 120 | } |
| 121 | |
| 122 | static inline int sigp_p(u32 parameter, int cpu, int order) |
| 123 | { |
| 124 | return raw_sigp_p(parameter, cpu_logical_map(cpu), order); |
| 125 | } |
| 126 | |
| 127 | static inline int sigp_ps(u32 *status, u32 parm, int cpu, int order) |
| 128 | { |
| 129 | return raw_sigp_ps(status, parm, cpu_logical_map(cpu), order); |
| 130 | } |
| 131 | |
| 132 | #endif /* __ASM_SIGP_H */ |