aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2010-02-26 16:37:35 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-02-26 16:37:30 -0500
commita93b8ec1df1f0ad75d036dbc0fdef2e0ccb7be02 (patch)
treea68ab05bfd48eb637e50e2294005d6e079098a7e /arch/s390
parent2c2df118a6440748e6fd71a510a66ee708c31494 (diff)
[S390] smp: rework sigp code
Rename signal_processor* functions to sigp*. Add raw variants of each version, so we can get rid of the hacks played in smp code which establish temporary cpu logical mappings so they could call the sigp functions. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/sigp.h100
-rw-r--r--arch/s390/kernel/ipl.c2
-rw-r--r--arch/s390/kernel/smp.c54
3 files changed, 74 insertions, 82 deletions
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index f72d611f7e13..8aa46ce4229c 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -1,24 +1,19 @@
1/* 1/*
2 * include/asm-s390/sigp.h 2 * Routines and structures for signalling other processors.
3 * 3 *
4 * S390 version 4 * Copyright IBM Corp. 1999,2010
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Author(s): Denis Joseph Barrow,
6 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>,
7 * Martin Schwidefsky (schwidefsky@de.ibm.com) 7 * Heiko Carstens <heiko.carstens@de.ibm.com>,
8 * Heiko Carstens (heiko.carstens@de.ibm.com)
9 *
10 * sigp.h by D.J. Barrow (c) IBM 1999
11 * contains routines / structures for signalling other S/390 processors in an
12 * SMP configuration.
13 */ 8 */
14 9
15#ifndef __SIGP__ 10#ifndef __ASM_SIGP_H
16#define __SIGP__ 11#define __ASM_SIGP_H
17 12
18#include <asm/system.h> 13#include <asm/system.h>
19 14
20/* get real cpu address from logical cpu number */ 15/* Get real cpu address from logical cpu number. */
21extern int __cpu_logical_map[]; 16extern unsigned short __cpu_logical_map[];
22 17
23static inline int cpu_logical_map(int cpu) 18static inline int cpu_logical_map(int cpu)
24{ 19{
@@ -29,8 +24,7 @@ static inline int cpu_logical_map(int cpu)
29#endif 24#endif
30} 25}
31 26
32typedef enum 27enum {
33{
34 sigp_unassigned=0x0, 28 sigp_unassigned=0x0,
35 sigp_sense, 29 sigp_sense,
36 sigp_external_call, 30 sigp_external_call,
@@ -47,89 +41,93 @@ typedef enum
47 sigp_set_prefix, 41 sigp_set_prefix,
48 sigp_store_status_at_address, 42 sigp_store_status_at_address,
49 sigp_store_extended_status_at_address 43 sigp_store_extended_status_at_address
50} sigp_order_code; 44};
51
52typedef __u32 sigp_status_word;
53 45
54typedef enum 46enum {
55{
56 sigp_order_code_accepted=0, 47 sigp_order_code_accepted=0,
57 sigp_status_stored, 48 sigp_status_stored,
58 sigp_busy, 49 sigp_busy,
59 sigp_not_operational 50 sigp_not_operational
60} sigp_ccode; 51};
61
62 52
63/* 53/*
64 * Definitions for the external call 54 * Definitions for external call.
65 */ 55 */
66 56enum {
67/* 'Bit' signals, asynchronous */ 57 ec_schedule = 0,
68typedef enum
69{
70 ec_schedule=0,
71 ec_call_function, 58 ec_call_function,
72 ec_call_function_single, 59 ec_call_function_single,
73 ec_bit_last 60 ec_bit_last
74} ec_bit_sig; 61};
75 62
76/* 63/*
77 * Signal processor 64 * Signal processor.
78 */ 65 */
79static inline sigp_ccode 66static inline int raw_sigp(u16 cpu, int order)
80signal_processor(__u16 cpu_addr, sigp_order_code order_code)
81{ 67{
82 register unsigned long reg1 asm ("1") = 0; 68 register unsigned long reg1 asm ("1") = 0;
83 sigp_ccode ccode; 69 int ccode;
84 70
85 asm volatile( 71 asm volatile(
86 " sigp %1,%2,0(%3)\n" 72 " sigp %1,%2,0(%3)\n"
87 " ipm %0\n" 73 " ipm %0\n"
88 " srl %0,28\n" 74 " srl %0,28\n"
89 : "=d" (ccode) 75 : "=d" (ccode)
90 : "d" (reg1), "d" (cpu_logical_map(cpu_addr)), 76 : "d" (reg1), "d" (cpu),
91 "a" (order_code) : "cc" , "memory"); 77 "a" (order) : "cc" , "memory");
92 return ccode; 78 return ccode;
93} 79}
94 80
95/* 81/*
96 * Signal processor with parameter 82 * Signal processor with parameter.
97 */ 83 */
98static inline sigp_ccode 84static inline int raw_sigp_p(u32 parameter, u16 cpu, int order)
99signal_processor_p(__u32 parameter, __u16 cpu_addr, sigp_order_code order_code)
100{ 85{
101 register unsigned int reg1 asm ("1") = parameter; 86 register unsigned int reg1 asm ("1") = parameter;
102 sigp_ccode ccode; 87 int ccode;
103 88
104 asm volatile( 89 asm volatile(
105 " sigp %1,%2,0(%3)\n" 90 " sigp %1,%2,0(%3)\n"
106 " ipm %0\n" 91 " ipm %0\n"
107 " srl %0,28\n" 92 " srl %0,28\n"
108 : "=d" (ccode) 93 : "=d" (ccode)
109 : "d" (reg1), "d" (cpu_logical_map(cpu_addr)), 94 : "d" (reg1), "d" (cpu),
110 "a" (order_code) : "cc" , "memory"); 95 "a" (order) : "cc" , "memory");
111 return ccode; 96 return ccode;
112} 97}
113 98
114/* 99/*
115 * Signal processor with parameter and return status 100 * Signal processor with parameter and return status.
116 */ 101 */
117static inline sigp_ccode 102static inline int raw_sigp_ps(u32 *status, u32 parm, u16 cpu, int order)
118signal_processor_ps(__u32 *statusptr, __u32 parameter, __u16 cpu_addr,
119 sigp_order_code order_code)
120{ 103{
121 register unsigned int reg1 asm ("1") = parameter; 104 register unsigned int reg1 asm ("1") = parm;
122 sigp_ccode ccode; 105 int ccode;
123 106
124 asm volatile( 107 asm volatile(
125 " sigp %1,%2,0(%3)\n" 108 " sigp %1,%2,0(%3)\n"
126 " ipm %0\n" 109 " ipm %0\n"
127 " srl %0,28\n" 110 " srl %0,28\n"
128 : "=d" (ccode), "+d" (reg1) 111 : "=d" (ccode), "+d" (reg1)
129 : "d" (cpu_logical_map(cpu_addr)), "a" (order_code) 112 : "d" (cpu), "a" (order)
130 : "cc" , "memory"); 113 : "cc" , "memory");
131 *statusptr = reg1; 114 *status = reg1;
132 return ccode; 115 return ccode;
133} 116}
134 117
135#endif /* __SIGP__ */ 118static inline int sigp(int cpu, int order)
119{
120 return raw_sigp(cpu_logical_map(cpu), order);
121}
122
123static inline int sigp_p(u32 parameter, int cpu, int order)
124{
125 return raw_sigp_p(parameter, cpu_logical_map(cpu), order);
126}
127
128static inline int sigp_ps(u32 *status, u32 parm, int cpu, int order)
129{
130 return raw_sigp_ps(status, parm, cpu_logical_map(cpu), order);
131}
132
133#endif /* __ASM_SIGP_H */
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 0a7c39dee6b7..ae9c564e375d 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1610,7 +1610,7 @@ static void stop_run(struct shutdown_trigger *trigger)
1610{ 1610{
1611 if (strcmp(trigger->name, ON_PANIC_STR) == 0) 1611 if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1612 disabled_wait((unsigned long) __builtin_return_address(0)); 1612 disabled_wait((unsigned long) __builtin_return_address(0));
1613 while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 1613 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
1614 cpu_relax(); 1614 cpu_relax();
1615 for (;;); 1615 for (;;);
1616} 1616}
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index b39f596d71bd..d8a0b115c7c1 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -53,7 +53,7 @@
53#include "entry.h" 53#include "entry.h"
54 54
55/* logical cpu to cpu address */ 55/* logical cpu to cpu address */
56int __cpu_logical_map[NR_CPUS]; 56unsigned short __cpu_logical_map[NR_CPUS];
57 57
58static struct task_struct *current_set[NR_CPUS]; 58static struct task_struct *current_set[NR_CPUS];
59 59
@@ -72,13 +72,13 @@ static int cpu_management;
72 72
73static DEFINE_PER_CPU(struct cpu, cpu_devices); 73static DEFINE_PER_CPU(struct cpu, cpu_devices);
74 74
75static void smp_ext_bitcall(int, ec_bit_sig); 75static void smp_ext_bitcall(int, int);
76 76
77static int cpu_stopped(int cpu) 77static int raw_cpu_stopped(int cpu)
78{ 78{
79 __u32 status; 79 u32 status;
80 80
81 switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { 81 switch (raw_sigp_ps(&status, 0, cpu, sigp_sense)) {
82 case sigp_status_stored: 82 case sigp_status_stored:
83 /* Check for stopped and check stop state */ 83 /* Check for stopped and check stop state */
84 if (status & 0x50) 84 if (status & 0x50)
@@ -90,6 +90,11 @@ static int cpu_stopped(int cpu)
90 return 0; 90 return 0;
91} 91}
92 92
93static inline int cpu_stopped(int cpu)
94{
95 return raw_cpu_stopped(cpu_logical_map(cpu));
96}
97
93void smp_switch_to_ipl_cpu(void (*func)(void *), void *data) 98void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
94{ 99{
95 struct _lowcore *lc, *current_lc; 100 struct _lowcore *lc, *current_lc;
@@ -110,7 +115,7 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
110 lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu; 115 lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
111 if (!cpu_online(0)) 116 if (!cpu_online(0))
112 smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]); 117 smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
113 while (signal_processor(0, sigp_stop_and_store_status) == sigp_busy) 118 while (sigp(0, sigp_stop_and_store_status) == sigp_busy)
114 cpu_relax(); 119 cpu_relax();
115 sp = lc->panic_stack; 120 sp = lc->panic_stack;
116 sp -= sizeof(struct pt_regs); 121 sp -= sizeof(struct pt_regs);
@@ -136,7 +141,7 @@ void smp_send_stop(void)
136 if (cpu == smp_processor_id()) 141 if (cpu == smp_processor_id())
137 continue; 142 continue;
138 do { 143 do {
139 rc = signal_processor(cpu, sigp_stop); 144 rc = sigp(cpu, sigp_stop);
140 } while (rc == sigp_busy); 145 } while (rc == sigp_busy);
141 146
142 while (!cpu_stopped(cpu)) 147 while (!cpu_stopped(cpu))
@@ -172,13 +177,13 @@ static void do_ext_call_interrupt(__u16 code)
172 * Send an external call sigp to another cpu and return without waiting 177 * Send an external call sigp to another cpu and return without waiting
173 * for its completion. 178 * for its completion.
174 */ 179 */
175static void smp_ext_bitcall(int cpu, ec_bit_sig sig) 180static void smp_ext_bitcall(int cpu, int sig)
176{ 181{
177 /* 182 /*
178 * Set signaling bit in lowcore of target cpu and kick it 183 * Set signaling bit in lowcore of target cpu and kick it
179 */ 184 */
180 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); 185 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
181 while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) 186 while (sigp(cpu, sigp_emergency_signal) == sigp_busy)
182 udelay(10); 187 udelay(10);
183} 188}
184 189
@@ -272,13 +277,6 @@ void smp_ctl_clear_bit(int cr, int bit)
272} 277}
273EXPORT_SYMBOL(smp_ctl_clear_bit); 278EXPORT_SYMBOL(smp_ctl_clear_bit);
274 279
275/*
276 * In early ipl state a temp. logically cpu number is needed, so the sigp
277 * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
278 * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
279 */
280#define CPU_INIT_NO 1
281
282#ifdef CONFIG_ZFCPDUMP 280#ifdef CONFIG_ZFCPDUMP
283 281
284static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) 282static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
@@ -291,9 +289,7 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
291 return; 289 return;
292 } 290 }
293 zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL); 291 zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
294 __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu; 292 while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
295 while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
296 sigp_busy)
297 cpu_relax(); 293 cpu_relax();
298 memcpy(zfcpdump_save_areas[cpu], 294 memcpy(zfcpdump_save_areas[cpu],
299 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, 295 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
@@ -409,8 +405,7 @@ static void __init smp_detect_cpus(void)
409 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { 405 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) {
410 if (cpu == boot_cpu_addr) 406 if (cpu == boot_cpu_addr)
411 continue; 407 continue;
412 __cpu_logical_map[CPU_INIT_NO] = cpu; 408 if (!raw_cpu_stopped(cpu))
413 if (!cpu_stopped(CPU_INIT_NO))
414 continue; 409 continue;
415 smp_get_save_area(c_cpus, cpu); 410 smp_get_save_area(c_cpus, cpu);
416 c_cpus++; 411 c_cpus++;
@@ -433,8 +428,7 @@ static void __init smp_detect_cpus(void)
433 cpu_addr = info->cpu[cpu].address; 428 cpu_addr = info->cpu[cpu].address;
434 if (cpu_addr == boot_cpu_addr) 429 if (cpu_addr == boot_cpu_addr)
435 continue; 430 continue;
436 __cpu_logical_map[CPU_INIT_NO] = cpu_addr; 431 if (!raw_cpu_stopped(cpu_addr)) {
437 if (!cpu_stopped(CPU_INIT_NO)) {
438 s_cpus++; 432 s_cpus++;
439 continue; 433 continue;
440 } 434 }
@@ -553,18 +547,18 @@ static void smp_free_lowcore(int cpu)
553/* Upping and downing of CPUs */ 547/* Upping and downing of CPUs */
554int __cpuinit __cpu_up(unsigned int cpu) 548int __cpuinit __cpu_up(unsigned int cpu)
555{ 549{
556 struct task_struct *idle;
557 struct _lowcore *cpu_lowcore; 550 struct _lowcore *cpu_lowcore;
551 struct task_struct *idle;
558 struct stack_frame *sf; 552 struct stack_frame *sf;
559 sigp_ccode ccode;
560 u32 lowcore; 553 u32 lowcore;
554 int ccode;
561 555
562 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) 556 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
563 return -EIO; 557 return -EIO;
564 if (smp_alloc_lowcore(cpu)) 558 if (smp_alloc_lowcore(cpu))
565 return -ENOMEM; 559 return -ENOMEM;
566 do { 560 do {
567 ccode = signal_processor(cpu, sigp_initial_cpu_reset); 561 ccode = sigp(cpu, sigp_initial_cpu_reset);
568 if (ccode == sigp_busy) 562 if (ccode == sigp_busy)
569 udelay(10); 563 udelay(10);
570 if (ccode == sigp_not_operational) 564 if (ccode == sigp_not_operational)
@@ -572,7 +566,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
572 } while (ccode == sigp_busy); 566 } while (ccode == sigp_busy);
573 567
574 lowcore = (u32)(unsigned long)lowcore_ptr[cpu]; 568 lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
575 while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy) 569 while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
576 udelay(10); 570 udelay(10);
577 571
578 idle = current_set[cpu]; 572 idle = current_set[cpu];
@@ -598,7 +592,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
598 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func; 592 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
599 eieio(); 593 eieio();
600 594
601 while (signal_processor(cpu, sigp_restart) == sigp_busy) 595 while (sigp(cpu, sigp_restart) == sigp_busy)
602 udelay(10); 596 udelay(10);
603 597
604 while (!cpu_online(cpu)) 598 while (!cpu_online(cpu))
@@ -660,7 +654,7 @@ void __cpu_die(unsigned int cpu)
660 /* Wait until target cpu is down */ 654 /* Wait until target cpu is down */
661 while (!cpu_stopped(cpu)) 655 while (!cpu_stopped(cpu))
662 cpu_relax(); 656 cpu_relax();
663 while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy) 657 while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
664 udelay(10); 658 udelay(10);
665 smp_free_lowcore(cpu); 659 smp_free_lowcore(cpu);
666 pr_info("Processor %d stopped\n", cpu); 660 pr_info("Processor %d stopped\n", cpu);
@@ -669,7 +663,7 @@ void __cpu_die(unsigned int cpu)
669void cpu_die(void) 663void cpu_die(void)
670{ 664{
671 idle_task_exit(); 665 idle_task_exit();
672 while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 666 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
673 cpu_relax(); 667 cpu_relax();
674 for (;;); 668 for (;;);
675} 669}