Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390: add support to start the kernel in 64 bit mode.

Do the switch to z/Architecture (alias 64 bit) mode early in head.S.
If the machine is already running in 64 bit mode the sigp turns into
a nop. With this change it doesn't matter in which mode the kernel
is started.

Reviewd-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

+70 -31
+70 -31
arch/s390/kernel/head.S
··· 52 52 .long 0x02000370,0x60000050 # the channel program the PSW 53 53 .long 0x020003c0,0x60000050 # at location 0 is loaded. 54 54 .long 0x02000410,0x60000050 # Initial processing starts 55 - .long 0x02000460,0x60000050 # at 0xf0 = iplstart. 55 + .long 0x02000460,0x60000050 # at 0x200 = iplstart. 56 56 .long 0x020004b0,0x60000050 57 57 .long 0x02000500,0x60000050 58 58 .long 0x02000550,0x60000050 ··· 62 62 .long 0x02000690,0x60000050 63 63 .long 0x020006e0,0x20000050 64 64 65 - .org 0xf0 65 + .org 0x200 66 + # 67 + # subroutine to set architecture mode 68 + # 69 + .Lsetmode: 70 + #ifdef CONFIG_64BIT 71 + mvi __LC_AR_MODE_ID,1 # set esame flag 72 + slr %r0,%r0 # set cpuid to zero 73 + lhi %r1,2 # mode 2 = esame (dump) 74 + sigp %r1,%r0,0x12 # switch to esame mode 75 + bras %r13,0f 76 + .fill 16,4,0x0 77 + 0: lmh %r0,%r15,0(%r13) # clear high-order half of gprs 78 + sam31 # switch to 31 bit addressing mode 79 + #else 80 + mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0) 81 + #endif 82 + br %r14 83 + 84 + # 85 + # subroutine to wait for end I/O 86 + # 87 + .Lirqwait: 88 + #ifdef CONFIG_64BIT 89 + mvc 0x1f0(16),.Lnewpsw # set up IO interrupt psw 90 + lpsw .Lwaitpsw 91 + .Lioint: 92 + br %r14 93 + .align 8 94 + .Lnewpsw: 95 + .quad 0x0000000080000000,.Lioint 96 + #else 97 + mvc 0x78(8),.Lnewpsw # set up IO interrupt psw 98 + lpsw .Lwaitpsw 99 + .Lioint: 100 + br %r14 101 + .align 8 102 + .Lnewpsw: 103 + .long 0x00080000,0x80000000+.Lioint 104 + #endif 105 + .Lwaitpsw: 106 + .long 0x020a0000,0x80000000+.Lioint 107 + 66 108 # 67 109 # subroutine for loading cards from the reader 68 110 # 69 111 .Lloader: 112 + la %r4,0(%r14) 70 113 la %r3,.Lorb # r2 = address of orb into r2 71 114 la %r5,.Lirb # r4 = address of irb 72 115 la %r6,.Lccws ··· 126 83 ssch 0(%r3) # load chunk of 1600 bytes 127 84 bnz .Llderr 128 85 .Lwait4irq: 129 - mvc 0x78(8),.Lnewpsw # set up IO interrupt psw 130 - lpsw .Lwaitpsw 131 - .Lioint: 86 + bas %r14,.Lirqwait 132 87 c %r1,0xb8 # compare subchannel number 133 88 bne .Lwait4irq 134 89 tsch 0(%r5) ··· 145 104 sr %r0,%r3 # #ccws*80-residual=#bytes read 146 105 ar %r2,%r0 147 106 148 - br %r14 # r2 contains the total size 107 + br %r4 # r2 contains the total size 149 108 150 109 .Lcont: 151 110 ahi %r2,0x640 # add 0x640 to total size ··· 169 128 .Lloadp:.long 0,0 170 129 .align 8 171 130 .Lcrash:.long 0x000a0000,0x00000000 172 - .Lnewpsw: 173 - .long 0x00080000,0x80000000+.Lioint 174 - .Lwaitpsw: 175 - .long 0x020a0000,0x80000000+.Lioint 176 131 177 132 .align 8 178 133 .Lccws: .rept 19 ··· 177 140 .long 0x02200050,0x00000000 178 141 179 142 iplstart: 143 + bas %r14,.Lsetmode # Immediately switch to 64 bit mode 180 144 lh %r1,0xb8 # test if subchannel number 181 145 bct %r1,.Lnoload # is valid 182 146 l %r1,0xb8 # load ipl subchannel number ··· 247 209 # 248 210 # reset files in VM reader 249 211 # 250 - stidp __LC_SAVE_AREA_SYNC # store cpuid 251 - tm __LC_SAVE_AREA_SYNC,0xff# running VM ? 212 + stidp .Lcpuid # store cpuid 213 + tm .Lcpuid,0xff # running VM ? 252 214 bno .Lnoreset 253 215 la %r2,.Lreset 254 216 lhi %r3,26 ··· 260 222 tm 31(%r5),0xff # bits is set in the schib 261 223 bz .Lnoreset 262 224 .Lwaitforirq: 263 - mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw 264 - .Lwaitrdrirq: 265 - lpsw .Lrdrwaitpsw 266 - .Lrdrint: 225 + bas %r14,.Lirqwait # wait for IO interrupt 267 226 c %r1,0xb8 # compare subchannel number 268 - bne .Lwaitrdrirq 227 + bne .Lwaitforirq 269 228 la %r5,.Lirb 270 229 tsch 0(%r5) 271 230 .Lnoreset: 272 231 b .Lnoload 273 - 274 - .align 8 275 - .Lrdrnewpsw: 276 - .long 0x00080000,0x80000000+.Lrdrint 277 - .Lrdrwaitpsw: 278 - .long 0x020a0000,0x80000000+.Lrdrint 279 232 280 233 # 281 234 # everything loaded, go for it ··· 283 254 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" 284 255 .L_eof: .long 0xc5d6c600 /* C'EOF' */ 285 256 .L_hdr: .long 0xc8c4d900 /* C'HDR' */ 257 + .align 8 258 + .Lcpuid:.fill 8,1,0 286 259 287 260 # 288 261 # SALIPL loader support. Based on a patch by Rob van der Heij. ··· 294 263 .org 0x800 295 264 ENTRY(start) 296 265 stm %r0,%r15,0x07b0 # store registers 266 + bas %r14,.Lsetmode # Immediately switch to 64 bit mode 297 267 basr %r12,%r0 298 268 .base: 299 269 l %r11,.parm ··· 375 343 ENTRY(startup_kdump) 376 344 j .Lep_startup_kdump 377 345 .Lep_startup_normal: 346 + #ifdef CONFIG_64BIT 347 + mvi __LC_AR_MODE_ID,1 # set esame flag 348 + slr %r0,%r0 # set cpuid to zero 349 + lhi %r1,2 # mode 2 = esame (dump) 350 + sigp %r1,%r0,0x12 # switch to esame mode 351 + bras %r13,0f 352 + .fill 16,4,0x0 353 + 0: lmh %r0,%r15,0(%r13) # clear high-order half of gprs 354 + sam31 # switch to 31 bit addressing mode 355 + #else 356 + mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0) 357 + #endif 378 358 basr %r13,0 # get base 379 359 .LPG0: 380 360 xc 0x200(256),0x200 # partially clear lowcore ··· 454 410 #endif 455 411 456 412 #ifdef CONFIG_64BIT 457 - mvi __LC_AR_MODE_ID,1 # set esame flag 458 - slr %r0,%r0 # set cpuid to zero 459 - lhi %r1,2 # mode 2 = esame (dump) 460 - sigp %r1,%r0,0x12 # switch to esame mode 413 + /* Continue with 64bit startup code in head64.S */ 461 414 sam64 # switch to 64 bit mode 462 - larl %r13,4f 463 - lmh %r0,%r15,0(%r13) # clear high-order half 464 415 jg startup_continue 465 - 4: .fill 16,4,0x0 466 416 #else 467 - mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0) 417 + /* Continue with 31bit startup code in head31.S */ 468 418 l %r13,4f-.LPG0(%r13) 469 419 b 0(%r13) 470 420 .align 8 471 421 4: .long startup_continue 472 422 #endif 423 + 473 424 .align 8 474 425 5: .long 0x7fffffff,0xffffffff 475 426