diff options
-rw-r--r-- | arch/s390/Kconfig | 4 | ||||
-rw-r--r-- | arch/s390/Makefile | 12 | ||||
-rw-r--r-- | arch/s390/defconfig | 21 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/head31.S | 15 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 16 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 33 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 10 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 182 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 10 | ||||
-rw-r--r-- | arch/s390/lib/delay.c | 7 | ||||
-rw-r--r-- | arch/s390/mm/init.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_quiesce.c | 1 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 3 | ||||
-rw-r--r-- | include/asm-s390/atomic.h | 2 | ||||
-rw-r--r-- | include/asm-s390/ipl.h | 113 | ||||
-rw-r--r-- | include/asm-s390/local.h | 59 | ||||
-rw-r--r-- | include/asm-s390/processor.h | 5 | ||||
-rw-r--r-- | include/asm-s390/sections.h | 2 | ||||
-rw-r--r-- | include/asm-s390/setup.h | 74 |
20 files changed, 269 insertions, 307 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index eaaac3788110..d9425f59be91 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -8,8 +8,8 @@ config MMU | |||
8 | default y | 8 | default y |
9 | 9 | ||
10 | config ZONE_DMA | 10 | config ZONE_DMA |
11 | bool | 11 | def_bool y |
12 | default y | 12 | depends on 64BIT |
13 | 13 | ||
14 | config LOCKDEP_SUPPORT | 14 | config LOCKDEP_SUPPORT |
15 | bool | 15 | bool |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 6598e5268573..b1e558496469 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -82,18 +82,18 @@ AFLAGS += $(aflags-y) | |||
82 | OBJCOPYFLAGS := -O binary | 82 | OBJCOPYFLAGS := -O binary |
83 | LDFLAGS_vmlinux := -e start | 83 | LDFLAGS_vmlinux := -e start |
84 | 84 | ||
85 | head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o | 85 | head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o |
86 | 86 | ||
87 | core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \ | 87 | core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ |
88 | arch/$(ARCH)/appldata/ arch/$(ARCH)/hypfs/ | 88 | arch/s390/appldata/ arch/s390/hypfs/ |
89 | libs-y += arch/$(ARCH)/lib/ | 89 | libs-y += arch/s390/lib/ |
90 | drivers-y += drivers/s390/ | 90 | drivers-y += drivers/s390/ |
91 | drivers-$(CONFIG_MATHEMU) += arch/$(ARCH)/math-emu/ | 91 | drivers-$(CONFIG_MATHEMU) += arch/s390/math-emu/ |
92 | 92 | ||
93 | # must be linked after kernel | 93 | # must be linked after kernel |
94 | drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ | 94 | drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ |
95 | 95 | ||
96 | boot := arch/$(ARCH)/boot | 96 | boot := arch/s390/boot |
97 | 97 | ||
98 | all: image | 98 | all: image |
99 | 99 | ||
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 1406400bf3ea..741d2bbb2b37 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -1,9 +1,10 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.20-rc1 | 3 | # Linux kernel version: 2.6.21-rc1 |
4 | # Fri Dec 15 16:52:28 2006 | 4 | # Wed Feb 21 10:44:30 2007 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_ZONE_DMA=y | ||
7 | CONFIG_LOCKDEP_SUPPORT=y | 8 | CONFIG_LOCKDEP_SUPPORT=y |
8 | CONFIG_STACKTRACE_SUPPORT=y | 9 | CONFIG_STACKTRACE_SUPPORT=y |
9 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 10 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
@@ -11,6 +12,7 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y | |||
11 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | 12 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set |
12 | CONFIG_GENERIC_HWEIGHT=y | 13 | CONFIG_GENERIC_HWEIGHT=y |
13 | CONFIG_GENERIC_TIME=y | 14 | CONFIG_GENERIC_TIME=y |
15 | CONFIG_NO_IOMEM=y | ||
14 | CONFIG_S390=y | 16 | CONFIG_S390=y |
15 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 17 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
16 | 18 | ||
@@ -29,6 +31,7 @@ CONFIG_LOCALVERSION_AUTO=y | |||
29 | CONFIG_SWAP=y | 31 | CONFIG_SWAP=y |
30 | CONFIG_SYSVIPC=y | 32 | CONFIG_SYSVIPC=y |
31 | # CONFIG_IPC_NS is not set | 33 | # CONFIG_IPC_NS is not set |
34 | CONFIG_SYSVIPC_SYSCTL=y | ||
32 | CONFIG_POSIX_MQUEUE=y | 35 | CONFIG_POSIX_MQUEUE=y |
33 | # CONFIG_BSD_PROCESS_ACCT is not set | 36 | # CONFIG_BSD_PROCESS_ACCT is not set |
34 | # CONFIG_TASKSTATS is not set | 37 | # CONFIG_TASKSTATS is not set |
@@ -133,6 +136,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y | |||
133 | # CONFIG_SPARSEMEM_STATIC is not set | 136 | # CONFIG_SPARSEMEM_STATIC is not set |
134 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 137 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
135 | CONFIG_RESOURCES_64BIT=y | 138 | CONFIG_RESOURCES_64BIT=y |
139 | CONFIG_ZONE_DMA_FLAG=1 | ||
136 | CONFIG_HOLES_IN_ZONE=y | 140 | CONFIG_HOLES_IN_ZONE=y |
137 | 141 | ||
138 | # | 142 | # |
@@ -178,7 +182,9 @@ CONFIG_UNIX=y | |||
178 | CONFIG_XFRM=y | 182 | CONFIG_XFRM=y |
179 | # CONFIG_XFRM_USER is not set | 183 | # CONFIG_XFRM_USER is not set |
180 | # CONFIG_XFRM_SUB_POLICY is not set | 184 | # CONFIG_XFRM_SUB_POLICY is not set |
185 | # CONFIG_XFRM_MIGRATE is not set | ||
181 | CONFIG_NET_KEY=y | 186 | CONFIG_NET_KEY=y |
187 | # CONFIG_NET_KEY_MIGRATE is not set | ||
182 | CONFIG_IUCV=m | 188 | CONFIG_IUCV=m |
183 | CONFIG_AFIUCV=m | 189 | CONFIG_AFIUCV=m |
184 | CONFIG_INET=y | 190 | CONFIG_INET=y |
@@ -195,7 +201,7 @@ CONFIG_IP_FIB_HASH=y | |||
195 | # CONFIG_INET_ESP is not set | 201 | # CONFIG_INET_ESP is not set |
196 | # CONFIG_INET_IPCOMP is not set | 202 | # CONFIG_INET_IPCOMP is not set |
197 | # CONFIG_INET_XFRM_TUNNEL is not set | 203 | # CONFIG_INET_XFRM_TUNNEL is not set |
198 | # CONFIG_INET_TUNNEL is not set | 204 | CONFIG_INET_TUNNEL=y |
199 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 205 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
200 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 206 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
201 | CONFIG_INET_XFRM_MODE_BEET=y | 207 | CONFIG_INET_XFRM_MODE_BEET=y |
@@ -313,6 +319,7 @@ CONFIG_STANDALONE=y | |||
313 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 319 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
314 | # CONFIG_FW_LOADER is not set | 320 | # CONFIG_FW_LOADER is not set |
315 | # CONFIG_DEBUG_DRIVER is not set | 321 | # CONFIG_DEBUG_DRIVER is not set |
322 | # CONFIG_DEBUG_DEVRES is not set | ||
316 | CONFIG_SYS_HYPERVISOR=y | 323 | CONFIG_SYS_HYPERVISOR=y |
317 | 324 | ||
318 | # | 325 | # |
@@ -686,13 +693,13 @@ CONFIG_HEADERS_CHECK=y | |||
686 | CONFIG_DEBUG_KERNEL=y | 693 | CONFIG_DEBUG_KERNEL=y |
687 | CONFIG_LOG_BUF_SHIFT=17 | 694 | CONFIG_LOG_BUF_SHIFT=17 |
688 | # CONFIG_SCHEDSTATS is not set | 695 | # CONFIG_SCHEDSTATS is not set |
696 | # CONFIG_TIMER_STATS is not set | ||
689 | # CONFIG_DEBUG_SLAB is not set | 697 | # CONFIG_DEBUG_SLAB is not set |
690 | CONFIG_DEBUG_PREEMPT=y | 698 | CONFIG_DEBUG_PREEMPT=y |
691 | # CONFIG_DEBUG_RT_MUTEXES is not set | 699 | # CONFIG_DEBUG_RT_MUTEXES is not set |
692 | # CONFIG_RT_MUTEX_TESTER is not set | 700 | # CONFIG_RT_MUTEX_TESTER is not set |
693 | CONFIG_DEBUG_SPINLOCK=y | 701 | CONFIG_DEBUG_SPINLOCK=y |
694 | CONFIG_DEBUG_MUTEXES=y | 702 | CONFIG_DEBUG_MUTEXES=y |
695 | # CONFIG_DEBUG_RWSEMS is not set | ||
696 | # CONFIG_DEBUG_LOCK_ALLOC is not set | 703 | # CONFIG_DEBUG_LOCK_ALLOC is not set |
697 | # CONFIG_PROVE_LOCKING is not set | 704 | # CONFIG_PROVE_LOCKING is not set |
698 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | 705 | CONFIG_DEBUG_SPINLOCK_SLEEP=y |
@@ -702,10 +709,10 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y | |||
702 | # CONFIG_DEBUG_VM is not set | 709 | # CONFIG_DEBUG_VM is not set |
703 | # CONFIG_DEBUG_LIST is not set | 710 | # CONFIG_DEBUG_LIST is not set |
704 | # CONFIG_FRAME_POINTER is not set | 711 | # CONFIG_FRAME_POINTER is not set |
705 | # CONFIG_UNWIND_INFO is not set | ||
706 | CONFIG_FORCED_INLINING=y | 712 | CONFIG_FORCED_INLINING=y |
707 | # CONFIG_RCU_TORTURE_TEST is not set | 713 | # CONFIG_RCU_TORTURE_TEST is not set |
708 | # CONFIG_LKDTM is not set | 714 | # CONFIG_LKDTM is not set |
715 | # CONFIG_FAULT_INJECTION is not set | ||
709 | 716 | ||
710 | # | 717 | # |
711 | # Security options | 718 | # Security options |
@@ -733,8 +740,10 @@ CONFIG_CRYPTO_MANAGER=y | |||
733 | # CONFIG_CRYPTO_GF128MUL is not set | 740 | # CONFIG_CRYPTO_GF128MUL is not set |
734 | CONFIG_CRYPTO_ECB=m | 741 | CONFIG_CRYPTO_ECB=m |
735 | CONFIG_CRYPTO_CBC=y | 742 | CONFIG_CRYPTO_CBC=y |
743 | CONFIG_CRYPTO_PCBC=m | ||
736 | # CONFIG_CRYPTO_LRW is not set | 744 | # CONFIG_CRYPTO_LRW is not set |
737 | # CONFIG_CRYPTO_DES is not set | 745 | # CONFIG_CRYPTO_DES is not set |
746 | CONFIG_CRYPTO_FCRYPT=m | ||
738 | # CONFIG_CRYPTO_BLOWFISH is not set | 747 | # CONFIG_CRYPTO_BLOWFISH is not set |
739 | # CONFIG_CRYPTO_TWOFISH is not set | 748 | # CONFIG_CRYPTO_TWOFISH is not set |
740 | # CONFIG_CRYPTO_SERPENT is not set | 749 | # CONFIG_CRYPTO_SERPENT is not set |
@@ -748,6 +757,7 @@ CONFIG_CRYPTO_CBC=y | |||
748 | # CONFIG_CRYPTO_DEFLATE is not set | 757 | # CONFIG_CRYPTO_DEFLATE is not set |
749 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | 758 | # CONFIG_CRYPTO_MICHAEL_MIC is not set |
750 | # CONFIG_CRYPTO_CRC32C is not set | 759 | # CONFIG_CRYPTO_CRC32C is not set |
760 | CONFIG_CRYPTO_CAMELLIA=m | ||
751 | # CONFIG_CRYPTO_TEST is not set | 761 | # CONFIG_CRYPTO_TEST is not set |
752 | 762 | ||
753 | # | 763 | # |
@@ -768,4 +778,3 @@ CONFIG_BITREVERSE=m | |||
768 | CONFIG_CRC32=m | 778 | CONFIG_CRC32=m |
769 | # CONFIG_LIBCRC32C is not set | 779 | # CONFIG_LIBCRC32C is not set |
770 | CONFIG_PLIST=y | 780 | CONFIG_PLIST=y |
771 | CONFIG_IOMAP_COPY=y | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index e518dd53eff5..afca1c6f4d21 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/pfn.h> | 15 | #include <linux/pfn.h> |
16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
17 | #include <asm/ipl.h> | ||
17 | #include <asm/lowcore.h> | 18 | #include <asm/lowcore.h> |
18 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
19 | #include <asm/sections.h> | 20 | #include <asm/sections.h> |
@@ -109,7 +110,7 @@ static inline void create_kernel_nss(void) { } | |||
109 | */ | 110 | */ |
110 | static noinline __init void clear_bss_section(void) | 111 | static noinline __init void clear_bss_section(void) |
111 | { | 112 | { |
112 | memset(__bss_start, 0, _end - __bss_start); | 113 | memset(__bss_start, 0, __bss_stop - __bss_start); |
113 | } | 114 | } |
114 | 115 | ||
115 | /* | 116 | /* |
@@ -129,7 +130,7 @@ static noinline __init void detect_machine_type(void) | |||
129 | { | 130 | { |
130 | struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; | 131 | struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; |
131 | 132 | ||
132 | asm volatile("stidp %0" : "=m" (S390_lowcore.cpu_data.cpu_id)); | 133 | get_cpu_id(&S390_lowcore.cpu_data.cpu_id); |
133 | 134 | ||
134 | /* Running under z/VM ? */ | 135 | /* Running under z/VM ? */ |
135 | if (cpuinfo->cpu_id.version == 0xff) | 136 | if (cpuinfo->cpu_id.version == 0xff) |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 453fd3b4edea..da7c8bb80982 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
@@ -148,20 +148,9 @@ startup_continue: | |||
148 | .Lstartup_init: | 148 | .Lstartup_init: |
149 | .long startup_init | 149 | .long startup_init |
150 | 150 | ||
151 | .globl ipl_schib | ||
152 | ipl_schib: | ||
153 | .rept 13 | ||
154 | .long 0 | ||
155 | .endr | ||
156 | |||
157 | .globl ipl_flags | ||
158 | ipl_flags: | ||
159 | .long 0 | ||
160 | .globl ipl_devno | ||
161 | ipl_devno: | ||
162 | .word 0 | ||
163 | |||
164 | .org 0x12000 | 151 | .org 0x12000 |
152 | .globl _ehead | ||
153 | _ehead: | ||
165 | #ifdef CONFIG_SHARED_KERNEL | 154 | #ifdef CONFIG_SHARED_KERNEL |
166 | .org 0x100000 | 155 | .org 0x100000 |
167 | #endif | 156 | #endif |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index b8fec4e5c5d4..af09e18cc5d0 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -154,21 +154,9 @@ startup_continue: | |||
154 | .Lparmaddr: | 154 | .Lparmaddr: |
155 | .quad PARMAREA | 155 | .quad PARMAREA |
156 | 156 | ||
157 | .globl ipl_schib | ||
158 | ipl_schib: | ||
159 | .rept 13 | ||
160 | .long 0 | ||
161 | .endr | ||
162 | |||
163 | .globl ipl_flags | ||
164 | ipl_flags: | ||
165 | .long 0 | ||
166 | .globl ipl_devno | ||
167 | ipl_devno: | ||
168 | .word 0 | ||
169 | |||
170 | .org 0x12000 | 157 | .org 0x12000 |
171 | 158 | .globl _ehead | |
159 | _ehead: | ||
172 | #ifdef CONFIG_SHARED_KERNEL | 160 | #ifdef CONFIG_SHARED_KERNEL |
173 | .org 0x100000 | 161 | .org 0x100000 |
174 | #endif | 162 | #endif |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 052259530651..5a863a3bf10c 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/reboot.h> | 15 | #include <linux/reboot.h> |
16 | #include <linux/ctype.h> | 16 | #include <linux/ctype.h> |
17 | #include <asm/ipl.h> | ||
17 | #include <asm/smp.h> | 18 | #include <asm/smp.h> |
18 | #include <asm/setup.h> | 19 | #include <asm/setup.h> |
19 | #include <asm/cpcmd.h> | 20 | #include <asm/cpcmd.h> |
@@ -42,6 +43,13 @@ enum ipl_type { | |||
42 | #define IPL_FCP_STR "fcp" | 43 | #define IPL_FCP_STR "fcp" |
43 | #define IPL_NSS_STR "nss" | 44 | #define IPL_NSS_STR "nss" |
44 | 45 | ||
46 | /* | ||
47 | * Must be in data section since the bss section | ||
48 | * is not cleared when these are accessed. | ||
49 | */ | ||
50 | u16 ipl_devno __attribute__((__section__(".data"))) = 0; | ||
51 | u32 ipl_flags __attribute__((__section__(".data"))) = 0; | ||
52 | |||
45 | static char *ipl_type_str(enum ipl_type type) | 53 | static char *ipl_type_str(enum ipl_type type) |
46 | { | 54 | { |
47 | switch (type) { | 55 | switch (type) { |
@@ -90,31 +98,10 @@ static char *shutdown_action_str(enum shutdown_action action) | |||
90 | case SHUTDOWN_STOP: | 98 | case SHUTDOWN_STOP: |
91 | return SHUTDOWN_STOP_STR; | 99 | return SHUTDOWN_STOP_STR; |
92 | default: | 100 | default: |
93 | BUG(); | 101 | return NULL; |
94 | } | 102 | } |
95 | } | 103 | } |
96 | 104 | ||
97 | enum diag308_subcode { | ||
98 | DIAG308_IPL = 3, | ||
99 | DIAG308_DUMP = 4, | ||
100 | DIAG308_SET = 5, | ||
101 | DIAG308_STORE = 6, | ||
102 | }; | ||
103 | |||
104 | enum diag308_ipl_type { | ||
105 | DIAG308_IPL_TYPE_FCP = 0, | ||
106 | DIAG308_IPL_TYPE_CCW = 2, | ||
107 | }; | ||
108 | |||
109 | enum diag308_opt { | ||
110 | DIAG308_IPL_OPT_IPL = 0x10, | ||
111 | DIAG308_IPL_OPT_DUMP = 0x20, | ||
112 | }; | ||
113 | |||
114 | enum diag308_rc { | ||
115 | DIAG308_RC_OK = 1, | ||
116 | }; | ||
117 | |||
118 | static int diag308_set_works = 0; | 105 | static int diag308_set_works = 0; |
119 | 106 | ||
120 | static int reipl_capabilities = IPL_TYPE_UNKNOWN; | 107 | static int reipl_capabilities = IPL_TYPE_UNKNOWN; |
@@ -134,7 +121,7 @@ static struct ipl_parameter_block *dump_block_ccw; | |||
134 | 121 | ||
135 | static enum shutdown_action on_panic_action = SHUTDOWN_STOP; | 122 | static enum shutdown_action on_panic_action = SHUTDOWN_STOP; |
136 | 123 | ||
137 | static int diag308(unsigned long subcode, void *addr) | 124 | int diag308(unsigned long subcode, void *addr) |
138 | { | 125 | { |
139 | register unsigned long _addr asm("0") = (unsigned long) addr; | 126 | register unsigned long _addr asm("0") = (unsigned long) addr; |
140 | register unsigned long _rc asm("1") = 0; | 127 | register unsigned long _rc asm("1") = 0; |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 50c5210fbc64..863c8d08c026 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/ctype.h> | 41 | #include <linux/ctype.h> |
42 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
43 | 43 | ||
44 | #include <asm/ipl.h> | ||
44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
46 | #include <asm/smp.h> | 47 | #include <asm/smp.h> |
@@ -106,7 +107,7 @@ void __devinit cpu_init (void) | |||
106 | /* | 107 | /* |
107 | * Store processor id in lowcore (used e.g. in timer_interrupt) | 108 | * Store processor id in lowcore (used e.g. in timer_interrupt) |
108 | */ | 109 | */ |
109 | asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); | 110 | get_cpu_id(&S390_lowcore.cpu_data.cpu_id); |
110 | S390_lowcore.cpu_data.cpu_addr = addr; | 111 | S390_lowcore.cpu_data.cpu_addr = addr; |
111 | 112 | ||
112 | /* | 113 | /* |
@@ -689,9 +690,14 @@ setup_memory(void) | |||
689 | psw_set_key(PAGE_DEFAULT_KEY); | 690 | psw_set_key(PAGE_DEFAULT_KEY); |
690 | 691 | ||
691 | free_bootmem_with_active_regions(0, max_pfn); | 692 | free_bootmem_with_active_regions(0, max_pfn); |
692 | reserve_bootmem(0, PFN_PHYS(start_pfn)); | ||
693 | 693 | ||
694 | /* | 694 | /* |
695 | * Reserve memory used for lowcore/command line/kernel image. | ||
696 | */ | ||
697 | reserve_bootmem(0, (unsigned long)_ehead); | ||
698 | reserve_bootmem((unsigned long)_stext, | ||
699 | PFN_PHYS(start_pfn) - (unsigned long)_stext); | ||
700 | /* | ||
695 | * Reserve the bootmem bitmap itself as well. We do this in two | 701 | * Reserve the bootmem bitmap itself as well. We do this in two |
696 | * steps (first step was init_bootmem()) because this catches | 702 | * steps (first step was init_bootmem()) because this catches |
697 | * the (very unlikely) case of us accidentally initializing the | 703 | * the (very unlikely) case of us accidentally initializing the |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 83a4ea6e3d60..ecaa432a99f8 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/cpu.h> | 32 | #include <linux/cpu.h> |
33 | #include <linux/timex.h> | 33 | #include <linux/timex.h> |
34 | #include <asm/ipl.h> | ||
34 | #include <asm/setup.h> | 35 | #include <asm/setup.h> |
35 | #include <asm/sigp.h> | 36 | #include <asm/sigp.h> |
36 | #include <asm/pgalloc.h> | 37 | #include <asm/pgalloc.h> |
@@ -54,19 +55,18 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE; | |||
54 | static struct task_struct *current_set[NR_CPUS]; | 55 | static struct task_struct *current_set[NR_CPUS]; |
55 | 56 | ||
56 | static void smp_ext_bitcall(int, ec_bit_sig); | 57 | static void smp_ext_bitcall(int, ec_bit_sig); |
57 | static void smp_ext_bitcall_others(ec_bit_sig); | ||
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Structure and data for smp_call_function(). This is designed to minimise | 60 | * Structure and data for __smp_call_function_map(). This is designed to |
61 | * static memory requirements. It also looks cleaner. | 61 | * minimise static memory requirements. It also looks cleaner. |
62 | */ | 62 | */ |
63 | static DEFINE_SPINLOCK(call_lock); | 63 | static DEFINE_SPINLOCK(call_lock); |
64 | 64 | ||
65 | struct call_data_struct { | 65 | struct call_data_struct { |
66 | void (*func) (void *info); | 66 | void (*func) (void *info); |
67 | void *info; | 67 | void *info; |
68 | atomic_t started; | 68 | cpumask_t started; |
69 | atomic_t finished; | 69 | cpumask_t finished; |
70 | int wait; | 70 | int wait; |
71 | }; | 71 | }; |
72 | 72 | ||
@@ -81,118 +81,113 @@ static void do_call_function(void) | |||
81 | void *info = call_data->info; | 81 | void *info = call_data->info; |
82 | int wait = call_data->wait; | 82 | int wait = call_data->wait; |
83 | 83 | ||
84 | atomic_inc(&call_data->started); | 84 | cpu_set(smp_processor_id(), call_data->started); |
85 | (*func)(info); | 85 | (*func)(info); |
86 | if (wait) | 86 | if (wait) |
87 | atomic_inc(&call_data->finished); | 87 | cpu_set(smp_processor_id(), call_data->finished);; |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | static void __smp_call_function_map(void (*func) (void *info), void *info, |
91 | * this function sends a 'generic call function' IPI to all other CPUs | 91 | int nonatomic, int wait, cpumask_t map) |
92 | * in the system. | ||
93 | */ | ||
94 | |||
95 | int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | ||
96 | int wait) | ||
97 | /* | ||
98 | * [SUMMARY] Run a function on all other CPUs. | ||
99 | * <func> The function to run. This must be fast and non-blocking. | ||
100 | * <info> An arbitrary pointer to pass to the function. | ||
101 | * <nonatomic> currently unused. | ||
102 | * <wait> If true, wait (atomically) until function has completed on other CPUs. | ||
103 | * [RETURNS] 0 on success, else a negative status code. Does not return until | ||
104 | * remote CPUs are nearly ready to execute <<func>> or are or have executed. | ||
105 | * | ||
106 | * You must not call this function with disabled interrupts or from a | ||
107 | * hardware interrupt handler. | ||
108 | */ | ||
109 | { | 92 | { |
110 | struct call_data_struct data; | 93 | struct call_data_struct data; |
111 | int cpus = num_online_cpus()-1; | 94 | int cpu, local = 0; |
112 | 95 | ||
113 | if (cpus <= 0) | 96 | /* |
114 | return 0; | 97 | * Can deadlock when interrupts are disabled or if in wrong context, |
98 | * caller must disable preemption | ||
99 | */ | ||
100 | WARN_ON(irqs_disabled() || in_irq() || preemptible()); | ||
115 | 101 | ||
116 | /* Can deadlock when interrupts are disabled or if in wrong context */ | 102 | /* |
117 | WARN_ON(irqs_disabled() || in_irq()); | 103 | * Check for local function call. We have to have the same call order |
104 | * as in on_each_cpu() because of machine_restart_smp(). | ||
105 | */ | ||
106 | if (cpu_isset(smp_processor_id(), map)) { | ||
107 | local = 1; | ||
108 | cpu_clear(smp_processor_id(), map); | ||
109 | } | ||
110 | |||
111 | cpus_and(map, map, cpu_online_map); | ||
112 | if (cpus_empty(map)) | ||
113 | goto out; | ||
118 | 114 | ||
119 | data.func = func; | 115 | data.func = func; |
120 | data.info = info; | 116 | data.info = info; |
121 | atomic_set(&data.started, 0); | 117 | data.started = CPU_MASK_NONE; |
122 | data.wait = wait; | 118 | data.wait = wait; |
123 | if (wait) | 119 | if (wait) |
124 | atomic_set(&data.finished, 0); | 120 | data.finished = CPU_MASK_NONE; |
125 | 121 | ||
126 | spin_lock_bh(&call_lock); | 122 | spin_lock_bh(&call_lock); |
127 | call_data = &data; | 123 | call_data = &data; |
128 | /* Send a message to all other CPUs and wait for them to respond */ | 124 | |
129 | smp_ext_bitcall_others(ec_call_function); | 125 | for_each_cpu_mask(cpu, map) |
126 | smp_ext_bitcall(cpu, ec_call_function); | ||
130 | 127 | ||
131 | /* Wait for response */ | 128 | /* Wait for response */ |
132 | while (atomic_read(&data.started) != cpus) | 129 | while (!cpus_equal(map, data.started)) |
133 | cpu_relax(); | 130 | cpu_relax(); |
134 | 131 | ||
135 | if (wait) | 132 | if (wait) |
136 | while (atomic_read(&data.finished) != cpus) | 133 | while (!cpus_equal(map, data.finished)) |
137 | cpu_relax(); | 134 | cpu_relax(); |
135 | |||
138 | spin_unlock_bh(&call_lock); | 136 | spin_unlock_bh(&call_lock); |
139 | 137 | ||
140 | return 0; | 138 | out: |
139 | local_irq_disable(); | ||
140 | if (local) | ||
141 | func(info); | ||
142 | local_irq_enable(); | ||
141 | } | 143 | } |
142 | 144 | ||
143 | /* | 145 | /* |
144 | * Call a function on one CPU | 146 | * smp_call_function: |
145 | * cpu : the CPU the function should be executed on | 147 | * @func: the function to run; this must be fast and non-blocking |
148 | * @info: an arbitrary pointer to pass to the function | ||
149 | * @nonatomic: unused | ||
150 | * @wait: if true, wait (atomically) until function has completed on other CPUs | ||
146 | * | 151 | * |
147 | * You must not call this function with disabled interrupts or from a | 152 | * Run a function on all other CPUs. |
148 | * hardware interrupt handler. You may call it from a bottom half. | ||
149 | * | 153 | * |
150 | * It is guaranteed that the called function runs on the specified CPU, | 154 | * You must not call this function with disabled interrupts or from a |
151 | * preemption is disabled. | 155 | * hardware interrupt handler. Must be called with preemption disabled. |
156 | * You may call it from a bottom half. | ||
152 | */ | 157 | */ |
153 | int smp_call_function_on(void (*func) (void *info), void *info, | 158 | int smp_call_function(void (*func) (void *info), void *info, int nonatomic, |
154 | int nonatomic, int wait, int cpu) | 159 | int wait) |
155 | { | 160 | { |
156 | struct call_data_struct data; | 161 | cpumask_t map; |
157 | int curr_cpu; | ||
158 | |||
159 | if (!cpu_online(cpu)) | ||
160 | return -EINVAL; | ||
161 | |||
162 | /* Can deadlock when interrupts are disabled or if in wrong context */ | ||
163 | WARN_ON(irqs_disabled() || in_irq()); | ||
164 | |||
165 | /* disable preemption for local function call */ | ||
166 | curr_cpu = get_cpu(); | ||
167 | |||
168 | if (curr_cpu == cpu) { | ||
169 | /* direct call to function */ | ||
170 | func(info); | ||
171 | put_cpu(); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | data.func = func; | ||
176 | data.info = info; | ||
177 | atomic_set(&data.started, 0); | ||
178 | data.wait = wait; | ||
179 | if (wait) | ||
180 | atomic_set(&data.finished, 0); | ||
181 | |||
182 | spin_lock_bh(&call_lock); | ||
183 | call_data = &data; | ||
184 | smp_ext_bitcall(cpu, ec_call_function); | ||
185 | 162 | ||
186 | /* Wait for response */ | 163 | map = cpu_online_map; |
187 | while (atomic_read(&data.started) != 1) | 164 | cpu_clear(smp_processor_id(), map); |
188 | cpu_relax(); | 165 | __smp_call_function_map(func, info, nonatomic, wait, map); |
166 | return 0; | ||
167 | } | ||
168 | EXPORT_SYMBOL(smp_call_function); | ||
189 | 169 | ||
190 | if (wait) | 170 | /* |
191 | while (atomic_read(&data.finished) != 1) | 171 | * smp_call_function_on: |
192 | cpu_relax(); | 172 | * @func: the function to run; this must be fast and non-blocking |
173 | * @info: an arbitrary pointer to pass to the function | ||
174 | * @nonatomic: unused | ||
175 | * @wait: if true, wait (atomically) until function has completed on other CPUs | ||
176 | * @cpu: the CPU where func should run | ||
177 | * | ||
178 | * Run a function on one processor. | ||
179 | * | ||
180 | * You must not call this function with disabled interrupts or from a | ||
181 | * hardware interrupt handler. Must be called with preemption disabled. | ||
182 | * You may call it from a bottom half. | ||
183 | */ | ||
184 | int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic, | ||
185 | int wait, int cpu) | ||
186 | { | ||
187 | cpumask_t map = CPU_MASK_NONE; | ||
193 | 188 | ||
194 | spin_unlock_bh(&call_lock); | 189 | cpu_set(cpu, map); |
195 | put_cpu(); | 190 | __smp_call_function_map(func, info, nonatomic, wait, map); |
196 | return 0; | 191 | return 0; |
197 | } | 192 | } |
198 | EXPORT_SYMBOL(smp_call_function_on); | 193 | EXPORT_SYMBOL(smp_call_function_on); |
@@ -325,26 +320,6 @@ static void smp_ext_bitcall(int cpu, ec_bit_sig sig) | |||
325 | udelay(10); | 320 | udelay(10); |
326 | } | 321 | } |
327 | 322 | ||
328 | /* | ||
329 | * Send an external call sigp to every other cpu in the system and | ||
330 | * return without waiting for its completion. | ||
331 | */ | ||
332 | static void smp_ext_bitcall_others(ec_bit_sig sig) | ||
333 | { | ||
334 | int cpu; | ||
335 | |||
336 | for_each_online_cpu(cpu) { | ||
337 | if (cpu == smp_processor_id()) | ||
338 | continue; | ||
339 | /* | ||
340 | * Set signaling bit in lowcore of target cpu and kick it | ||
341 | */ | ||
342 | set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); | ||
343 | while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) | ||
344 | udelay(10); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | #ifndef CONFIG_64BIT | 323 | #ifndef CONFIG_64BIT |
349 | /* | 324 | /* |
350 | * this function sends a 'purge tlb' signal to another CPU. | 325 | * this function sends a 'purge tlb' signal to another CPU. |
@@ -807,6 +782,5 @@ EXPORT_SYMBOL(cpu_possible_map); | |||
807 | EXPORT_SYMBOL(lowcore_ptr); | 782 | EXPORT_SYMBOL(lowcore_ptr); |
808 | EXPORT_SYMBOL(smp_ctl_set_bit); | 783 | EXPORT_SYMBOL(smp_ctl_set_bit); |
809 | EXPORT_SYMBOL(smp_ctl_clear_bit); | 784 | EXPORT_SYMBOL(smp_ctl_clear_bit); |
810 | EXPORT_SYMBOL(smp_call_function); | ||
811 | EXPORT_SYMBOL(smp_get_cpu); | 785 | EXPORT_SYMBOL(smp_get_cpu); |
812 | EXPORT_SYMBOL(smp_put_cpu); | 786 | EXPORT_SYMBOL(smp_put_cpu); |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index ee9fd7b85928..e1ad464b6f20 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -747,6 +747,7 @@ static void etr_adjust_time(unsigned long long clock, unsigned long long delay) | |||
747 | } | 747 | } |
748 | } | 748 | } |
749 | 749 | ||
750 | #ifdef CONFIG_SMP | ||
750 | static void etr_sync_cpu_start(void *dummy) | 751 | static void etr_sync_cpu_start(void *dummy) |
751 | { | 752 | { |
752 | int *in_sync = dummy; | 753 | int *in_sync = dummy; |
@@ -758,8 +759,14 @@ static void etr_sync_cpu_start(void *dummy) | |||
758 | * __udelay will stop the cpu on an enabled wait psw until the | 759 | * __udelay will stop the cpu on an enabled wait psw until the |
759 | * TOD is running again. | 760 | * TOD is running again. |
760 | */ | 761 | */ |
761 | while (*in_sync == 0) | 762 | while (*in_sync == 0) { |
762 | __udelay(1); | 763 | __udelay(1); |
764 | /* | ||
765 | * A different cpu changes *in_sync. Therefore use | ||
766 | * barrier() to force memory access. | ||
767 | */ | ||
768 | barrier(); | ||
769 | } | ||
763 | if (*in_sync != 1) | 770 | if (*in_sync != 1) |
764 | /* Didn't work. Clear per-cpu in sync bit again. */ | 771 | /* Didn't work. Clear per-cpu in sync bit again. */ |
765 | etr_disable_sync_clock(NULL); | 772 | etr_disable_sync_clock(NULL); |
@@ -773,6 +780,7 @@ static void etr_sync_cpu_start(void *dummy) | |||
773 | static void etr_sync_cpu_end(void *dummy) | 780 | static void etr_sync_cpu_end(void *dummy) |
774 | { | 781 | { |
775 | } | 782 | } |
783 | #endif /* CONFIG_SMP */ | ||
776 | 784 | ||
777 | /* | 785 | /* |
778 | * Sync the TOD clock using the port refered to by aibp. This port | 786 | * Sync the TOD clock using the port refered to by aibp. This port |
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 02854449b74b..70f2a862b670 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/timex.h> | 16 | #include <linux/timex.h> |
17 | #include <linux/irqflags.h> | 17 | #include <linux/irqflags.h> |
18 | #include <linux/interrupt.h> | ||
18 | 19 | ||
19 | void __delay(unsigned long loops) | 20 | void __delay(unsigned long loops) |
20 | { | 21 | { |
@@ -35,7 +36,11 @@ void __udelay(unsigned long usecs) | |||
35 | { | 36 | { |
36 | u64 end, time, jiffy_timer = 0; | 37 | u64 end, time, jiffy_timer = 0; |
37 | unsigned long flags, cr0, mask, dummy; | 38 | unsigned long flags, cr0, mask, dummy; |
39 | int irq_context; | ||
38 | 40 | ||
41 | irq_context = in_interrupt(); | ||
42 | if (!irq_context) | ||
43 | local_bh_disable(); | ||
39 | local_irq_save(flags); | 44 | local_irq_save(flags); |
40 | if (raw_irqs_disabled_flags(flags)) { | 45 | if (raw_irqs_disabled_flags(flags)) { |
41 | jiffy_timer = S390_lowcore.jiffy_timer; | 46 | jiffy_timer = S390_lowcore.jiffy_timer; |
@@ -62,6 +67,8 @@ void __udelay(unsigned long usecs) | |||
62 | __ctl_load(cr0, 0, 0); | 67 | __ctl_load(cr0, 0, 0); |
63 | S390_lowcore.jiffy_timer = jiffy_timer; | 68 | S390_lowcore.jiffy_timer = jiffy_timer; |
64 | } | 69 | } |
70 | if (!irq_context) | ||
71 | _local_bh_enable(); | ||
65 | set_clock_comparator(S390_lowcore.jiffy_timer); | 72 | set_clock_comparator(S390_lowcore.jiffy_timer); |
66 | local_irq_restore(flags); | 73 | local_irq_restore(flags); |
67 | } | 74 | } |
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index b3e7c45efb63..916b72a8cde8 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -141,7 +141,9 @@ void __init paging_init(void) | |||
141 | __raw_local_irq_ssm(ssm_mask); | 141 | __raw_local_irq_ssm(ssm_mask); |
142 | 142 | ||
143 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); | 143 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); |
144 | #ifdef CONFIG_ZONE_DMA | ||
144 | max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); | 145 | max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); |
146 | #endif | ||
145 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; | 147 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; |
146 | free_area_init_nodes(max_zone_pfns); | 148 | free_area_init_nodes(max_zone_pfns); |
147 | } | 149 | } |
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c index ffa9282ce97a..baa8fe669ed2 100644 --- a/drivers/s390/char/sclp_quiesce.c +++ b/drivers/s390/char/sclp_quiesce.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/atomic.h> | 16 | #include <asm/atomic.h> |
17 | #include <asm/ptrace.h> | 17 | #include <asm/ptrace.h> |
18 | #include <asm/sigp.h> | 18 | #include <asm/sigp.h> |
19 | #include <asm/smp.h> | ||
19 | 20 | ||
20 | #include "sclp.h" | 21 | #include "sclp.h" |
21 | 22 | ||
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index b3a56dc5f68a..9cb129ab5be5 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/irq_regs.h> | 21 | #include <asm/irq_regs.h> |
22 | #include <asm/setup.h> | 22 | #include <asm/setup.h> |
23 | #include <asm/reset.h> | 23 | #include <asm/reset.h> |
24 | #include <asm/ipl.h> | ||
24 | #include "airq.h" | 25 | #include "airq.h" |
25 | #include "cio.h" | 26 | #include "cio.h" |
26 | #include "css.h" | 27 | #include "css.h" |
@@ -1047,7 +1048,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) | |||
1047 | do_reipl_asm(*((__u32*)&schid)); | 1048 | do_reipl_asm(*((__u32*)&schid)); |
1048 | } | 1049 | } |
1049 | 1050 | ||
1050 | extern struct schib ipl_schib; | 1051 | static struct schib __initdata ipl_schib; |
1051 | 1052 | ||
1052 | /* | 1053 | /* |
1053 | * ipl_save_parameters gets called very early. It is not allowed to access | 1054 | * ipl_save_parameters gets called very early. It is not allowed to access |
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index af20c7462485..c17bdbf22067 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h | |||
@@ -215,6 +215,8 @@ static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) | |||
215 | __CSG_LOOP(v, mask, "ogr"); | 215 | __CSG_LOOP(v, mask, "ogr"); |
216 | } | 216 | } |
217 | 217 | ||
218 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | ||
219 | |||
218 | static __inline__ long long atomic64_cmpxchg(atomic64_t *v, | 220 | static __inline__ long long atomic64_cmpxchg(atomic64_t *v, |
219 | long long old, long long new) | 221 | long long old, long long new) |
220 | { | 222 | { |
diff --git a/include/asm-s390/ipl.h b/include/asm-s390/ipl.h new file mode 100644 index 000000000000..5650d3d4ae46 --- /dev/null +++ b/include/asm-s390/ipl.h | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * s390 (re)ipl support | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | */ | ||
6 | |||
7 | #ifndef _ASM_S390_IPL_H | ||
8 | #define _ASM_S390_IPL_H | ||
9 | |||
10 | #include <asm/types.h> | ||
11 | |||
12 | #define IPL_PARMBLOCK_ORIGIN 0x2000 | ||
13 | |||
14 | #define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \ | ||
15 | sizeof(struct ipl_block_fcp)) | ||
16 | |||
17 | #define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \ | ||
18 | sizeof(struct ipl_block_ccw)) | ||
19 | |||
20 | #define IPL_MAX_SUPPORTED_VERSION (0) | ||
21 | |||
22 | #define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \ | ||
23 | IPL_PARMBLOCK_ORIGIN) | ||
24 | #define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len) | ||
25 | |||
26 | struct ipl_list_hdr { | ||
27 | u32 len; | ||
28 | u8 reserved1[3]; | ||
29 | u8 version; | ||
30 | u32 blk0_len; | ||
31 | u8 pbt; | ||
32 | u8 flags; | ||
33 | u16 reserved2; | ||
34 | } __attribute__((packed)); | ||
35 | |||
36 | struct ipl_block_fcp { | ||
37 | u8 reserved1[313-1]; | ||
38 | u8 opt; | ||
39 | u8 reserved2[3]; | ||
40 | u16 reserved3; | ||
41 | u16 devno; | ||
42 | u8 reserved4[4]; | ||
43 | u64 wwpn; | ||
44 | u64 lun; | ||
45 | u32 bootprog; | ||
46 | u8 reserved5[12]; | ||
47 | u64 br_lba; | ||
48 | u32 scp_data_len; | ||
49 | u8 reserved6[260]; | ||
50 | u8 scp_data[]; | ||
51 | } __attribute__((packed)); | ||
52 | |||
53 | struct ipl_block_ccw { | ||
54 | u8 load_param[8]; | ||
55 | u8 reserved1[84]; | ||
56 | u8 reserved2[2]; | ||
57 | u16 devno; | ||
58 | u8 vm_flags; | ||
59 | u8 reserved3[3]; | ||
60 | u32 vm_parm_len; | ||
61 | } __attribute__((packed)); | ||
62 | |||
63 | struct ipl_parameter_block { | ||
64 | struct ipl_list_hdr hdr; | ||
65 | union { | ||
66 | struct ipl_block_fcp fcp; | ||
67 | struct ipl_block_ccw ccw; | ||
68 | } ipl_info; | ||
69 | } __attribute__((packed)); | ||
70 | |||
71 | /* | ||
72 | * IPL validity flags and parameters as detected in head.S | ||
73 | */ | ||
74 | extern u32 ipl_flags; | ||
75 | extern u16 ipl_devno; | ||
76 | |||
77 | extern void do_reipl(void); | ||
78 | extern void ipl_save_parameters(void); | ||
79 | |||
80 | enum { | ||
81 | IPL_DEVNO_VALID = 1, | ||
82 | IPL_PARMBLOCK_VALID = 2, | ||
83 | IPL_NSS_VALID = 4, | ||
84 | }; | ||
85 | |||
86 | /* | ||
87 | * DIAG 308 support | ||
88 | */ | ||
89 | enum diag308_subcode { | ||
90 | DIAG308_REL_HSA = 2, | ||
91 | DIAG308_IPL = 3, | ||
92 | DIAG308_DUMP = 4, | ||
93 | DIAG308_SET = 5, | ||
94 | DIAG308_STORE = 6, | ||
95 | }; | ||
96 | |||
97 | enum diag308_ipl_type { | ||
98 | DIAG308_IPL_TYPE_FCP = 0, | ||
99 | DIAG308_IPL_TYPE_CCW = 2, | ||
100 | }; | ||
101 | |||
102 | enum diag308_opt { | ||
103 | DIAG308_IPL_OPT_IPL = 0x10, | ||
104 | DIAG308_IPL_OPT_DUMP = 0x20, | ||
105 | }; | ||
106 | |||
107 | enum diag308_rc { | ||
108 | DIAG308_RC_OK = 1, | ||
109 | }; | ||
110 | |||
111 | extern int diag308(unsigned long subcode, void *addr); | ||
112 | |||
113 | #endif /* _ASM_S390_IPL_H */ | ||
diff --git a/include/asm-s390/local.h b/include/asm-s390/local.h index 86745a1b29bb..c11c530f74d0 100644 --- a/include/asm-s390/local.h +++ b/include/asm-s390/local.h | |||
@@ -1,58 +1 @@ | |||
1 | #ifndef _ASM_LOCAL_H | #include <asm-generic/local.h> | |
2 | #define _ASM_LOCAL_H | ||
3 | |||
4 | #include <linux/percpu.h> | ||
5 | #include <asm/atomic.h> | ||
6 | |||
7 | #ifndef __s390x__ | ||
8 | |||
9 | typedef atomic_t local_t; | ||
10 | |||
11 | #define LOCAL_INIT(i) ATOMIC_INIT(i) | ||
12 | #define local_read(v) atomic_read(v) | ||
13 | #define local_set(v,i) atomic_set(v,i) | ||
14 | |||
15 | #define local_inc(v) atomic_inc(v) | ||
16 | #define local_dec(v) atomic_dec(v) | ||
17 | #define local_add(i, v) atomic_add(i, v) | ||
18 | #define local_sub(i, v) atomic_sub(i, v) | ||
19 | |||
20 | #else | ||
21 | |||
22 | typedef atomic64_t local_t; | ||
23 | |||
24 | #define LOCAL_INIT(i) ATOMIC64_INIT(i) | ||
25 | #define local_read(v) atomic64_read(v) | ||
26 | #define local_set(v,i) atomic64_set(v,i) | ||
27 | |||
28 | #define local_inc(v) atomic64_inc(v) | ||
29 | #define local_dec(v) atomic64_dec(v) | ||
30 | #define local_add(i, v) atomic64_add(i, v) | ||
31 | #define local_sub(i, v) atomic64_sub(i, v) | ||
32 | |||
33 | #endif | ||
34 | |||
35 | #define __local_inc(v) ((v)->counter++) | ||
36 | #define __local_dec(v) ((v)->counter--) | ||
37 | #define __local_add(i,v) ((v)->counter+=(i)) | ||
38 | #define __local_sub(i,v) ((v)->counter-=(i)) | ||
39 | |||
40 | /* | ||
41 | * Use these for per-cpu local_t variables: on some archs they are | ||
42 | * much more efficient than these naive implementations. Note they take | ||
43 | * a variable, not an address. | ||
44 | */ | ||
45 | #define cpu_local_read(v) local_read(&__get_cpu_var(v)) | ||
46 | #define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i)) | ||
47 | |||
48 | #define cpu_local_inc(v) local_inc(&__get_cpu_var(v)) | ||
49 | #define cpu_local_dec(v) local_dec(&__get_cpu_var(v)) | ||
50 | #define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v)) | ||
51 | #define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v)) | ||
52 | |||
53 | #define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v)) | ||
54 | #define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v)) | ||
55 | #define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v)) | ||
56 | #define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v)) | ||
57 | |||
58 | #endif /* _ASM_LOCAL_H */ | ||
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index 4c1b73940351..33b80ced4bc1 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h | |||
@@ -36,6 +36,11 @@ typedef struct | |||
36 | unsigned int unused : 16; | 36 | unsigned int unused : 16; |
37 | } __attribute__ ((packed)) cpuid_t; | 37 | } __attribute__ ((packed)) cpuid_t; |
38 | 38 | ||
39 | static inline void get_cpu_id(cpuid_t *ptr) | ||
40 | { | ||
41 | asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); | ||
42 | } | ||
43 | |||
39 | struct cpuinfo_S390 | 44 | struct cpuinfo_S390 |
40 | { | 45 | { |
41 | cpuid_t cpu_id; | 46 | cpuid_t cpu_id; |
diff --git a/include/asm-s390/sections.h b/include/asm-s390/sections.h index 1c5a2c4ccdad..fbd9116eb17b 100644 --- a/include/asm-s390/sections.h +++ b/include/asm-s390/sections.h | |||
@@ -3,6 +3,6 @@ | |||
3 | 3 | ||
4 | #include <asm-generic/sections.h> | 4 | #include <asm-generic/sections.h> |
5 | 5 | ||
6 | extern char _eshared[]; | 6 | extern char _eshared[], _ehead[]; |
7 | 7 | ||
8 | #endif | 8 | #endif |
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index 3388bb52597c..44c7aee2bd34 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | #define PARMAREA 0x10400 | 17 | #define PARMAREA 0x10400 |
18 | #define MEMORY_CHUNKS 16 /* max 0x7fff */ | 18 | #define MEMORY_CHUNKS 16 /* max 0x7fff */ |
19 | #define IPL_PARMBLOCK_ORIGIN 0x2000 | ||
20 | 19 | ||
21 | #ifndef __ASSEMBLY__ | 20 | #ifndef __ASSEMBLY__ |
22 | 21 | ||
@@ -97,82 +96,9 @@ extern char vmpoff_cmd[]; | |||
97 | #define SET_CONSOLE_3215 do { console_mode = 2; } while (0) | 96 | #define SET_CONSOLE_3215 do { console_mode = 2; } while (0) |
98 | #define SET_CONSOLE_3270 do { console_mode = 3; } while (0) | 97 | #define SET_CONSOLE_3270 do { console_mode = 3; } while (0) |
99 | 98 | ||
100 | struct ipl_list_hdr { | ||
101 | u32 len; | ||
102 | u8 reserved1[3]; | ||
103 | u8 version; | ||
104 | u32 blk0_len; | ||
105 | u8 pbt; | ||
106 | u8 flags; | ||
107 | u16 reserved2; | ||
108 | } __attribute__((packed)); | ||
109 | |||
110 | struct ipl_block_fcp { | ||
111 | u8 reserved1[313-1]; | ||
112 | u8 opt; | ||
113 | u8 reserved2[3]; | ||
114 | u16 reserved3; | ||
115 | u16 devno; | ||
116 | u8 reserved4[4]; | ||
117 | u64 wwpn; | ||
118 | u64 lun; | ||
119 | u32 bootprog; | ||
120 | u8 reserved5[12]; | ||
121 | u64 br_lba; | ||
122 | u32 scp_data_len; | ||
123 | u8 reserved6[260]; | ||
124 | u8 scp_data[]; | ||
125 | } __attribute__((packed)); | ||
126 | |||
127 | struct ipl_block_ccw { | ||
128 | u8 load_param[8]; | ||
129 | u8 reserved1[84]; | ||
130 | u8 reserved2[2]; | ||
131 | u16 devno; | ||
132 | u8 vm_flags; | ||
133 | u8 reserved3[3]; | ||
134 | u32 vm_parm_len; | ||
135 | } __attribute__((packed)); | ||
136 | |||
137 | struct ipl_parameter_block { | ||
138 | struct ipl_list_hdr hdr; | ||
139 | union { | ||
140 | struct ipl_block_fcp fcp; | ||
141 | struct ipl_block_ccw ccw; | ||
142 | } ipl_info; | ||
143 | } __attribute__((packed)); | ||
144 | |||
145 | #define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \ | ||
146 | sizeof(struct ipl_block_fcp)) | ||
147 | |||
148 | #define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \ | ||
149 | sizeof(struct ipl_block_ccw)) | ||
150 | |||
151 | #define IPL_MAX_SUPPORTED_VERSION (0) | ||
152 | |||
153 | /* | ||
154 | * IPL validity flags and parameters as detected in head.S | ||
155 | */ | ||
156 | extern u32 ipl_flags; | ||
157 | extern u16 ipl_devno; | ||
158 | |||
159 | extern void do_reipl(void); | ||
160 | extern void ipl_save_parameters(void); | ||
161 | |||
162 | enum { | ||
163 | IPL_DEVNO_VALID = 1, | ||
164 | IPL_PARMBLOCK_VALID = 2, | ||
165 | IPL_NSS_VALID = 4, | ||
166 | }; | ||
167 | |||
168 | #define NSS_NAME_SIZE 8 | 99 | #define NSS_NAME_SIZE 8 |
169 | |||
170 | extern char kernel_nss_name[]; | 100 | extern char kernel_nss_name[]; |
171 | 101 | ||
172 | #define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \ | ||
173 | IPL_PARMBLOCK_ORIGIN) | ||
174 | #define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len) | ||
175 | |||
176 | #else /* __ASSEMBLY__ */ | 102 | #else /* __ASSEMBLY__ */ |
177 | 103 | ||
178 | #ifndef __s390x__ | 104 | #ifndef __s390x__ |