summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/head64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/head64.S')
-rw-r--r--arch/s390/kernel/head64.S72
1 files changed, 71 insertions, 1 deletions
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 37010709fe68..a87b1976d409 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -39,7 +39,69 @@ startup_continue:
basr %r13,0 # get base
.LPG1: sll %r13,1 # remove high order bit
srl %r13,1
- lhi %r1,1 # mode 1 = esame
+
+#ifdef CONFIG_ZFCPDUMP
+
+ # check if we have been ipled using zfcp dump:
+
+ tm 0xb9,0x01 # test if subchannel is enabled
+ jno .nodump # subchannel disabled
+ l %r1,0xb8
+ la %r5,.Lipl_schib-.LPG1(%r13)
+ stsch 0(%r5) # get schib of subchannel
+ jne .nodump # schib not available
+ tm 5(%r5),0x01 # devno valid?
+ jno .nodump
+ tm 4(%r5),0x80 # qdio capable device?
+ jno .nodump
+ l %r2,20(%r0) # address of ipl parameter block
+ lhi %r3,0
+ ic %r3,0x148(%r2) # get opt field
+ chi %r3,0x20 # load with dump?
+ jne .nodump
+
+ # store all prefix registers in case of load with dump:
+
+ la %r7,0 # base register for 0 page
+ la %r8,0 # first cpu
+ l %r11,.Lpref_arr_ptr-.LPG1(%r13) # address of prefix array
+ ahi %r11,4 # skip boot cpu
+ lr %r12,%r11
+ ahi %r12,(CONFIG_NR_CPUS*4) # end of prefix array
+ stap .Lcurrent_cpu+2-.LPG1(%r13) # store current cpu addr
+1:
+ cl %r8,.Lcurrent_cpu-.LPG1(%r13) # is ipl cpu ?
+ je 4f # if yes get next cpu
+2:
+ lr %r9,%r7
+ sigp %r9,%r8,0x9 # stop & store status of cpu
+ brc 8,3f # accepted
+ brc 4,4f # status stored: next cpu
+ brc 2,2b # busy: try again
+ brc 1,4f # not op: next cpu
+3:
+ mvc 0(4,%r11),264(%r7) # copy prefix register to prefix array
+ ahi %r11,4 # next element in prefix array
+ clr %r11,%r12
+ je 5f # no more space in prefix array
+4:
+ ahi %r8,1 # next cpu (r8 += 1)
+ cl %r8,.Llast_cpu-.LPG1(%r13) # is last possible cpu ?
+ jl 1b # jump if not last cpu
+5:
+ lhi %r1,2 # mode 2 = esame (dump)
+ j 6f
+ .align 4
+.Lipl_schib:
+ .rept 13
+ .long 0
+ .endr
+.nodump:
+ lhi %r1,1 # mode 1 = esame (normal ipl)
+6:
+#else
+ lhi %r1,1 # mode 1 = esame (normal ipl)
+#endif /* CONFIG_ZFCPDUMP */
mvi __LC_AR_MODE_ID,1 # set esame flag
slr %r0,%r0 # set cpuid to zero
sigp %r1,%r0,0x12 # switch to esame mode
@@ -149,6 +211,14 @@ startup_continue:
.L4malign:.quad 0xffffffffffc00000
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
.Lnop: .long 0x07000700
+#ifdef CONFIG_ZFCPDUMP
+.Lcurrent_cpu:
+ .long 0x0
+.Llast_cpu:
+ .long 0x0000ffff
+.Lpref_arr_ptr:
+ .long zfcpdump_prefix_array
+#endif /* CONFIG_ZFCPDUMP */
.Lparmaddr:
.quad PARMAREA
.align 64