patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / arch / s390 / kernel / head.S
index 229f4af..068653a 100644 (file)
@@ -478,9 +478,80 @@ startup:basr  %r13,0                     # get base
         mvcle %r2,%r4,0                 # clear mem
         jo    .-4                       # branch back, if not finish
 
+       l     %r2,.Lrcp-.LPG1(%r13)     # Read SCP forced command word
+.Lservicecall:
+       stosm .Lpmask-.LPG1(%r13),0x01  # authorize ext interrupts
+
+       stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
+       la    %r1,0x200                 # set bit 22
+       o     %r1,.Lcr-.LPG1(%r13)      # or old cr0 with r1
+       st    %r1,.Lcr-.LPG1(%r13)
+       lctl  %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
+
+       mvc   __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
+       la    %r1, .Lsclph-.LPG1(%r13)
+       a     %r1,__LC_EXT_NEW_PSW+4    # set handler
+       st    %r1,__LC_EXT_NEW_PSW+4
+
+       la    %r4,_pstart-.LPG1(%r13)   # %r4 is our index for sccb stuff
+       la    %r1, .Lsccb-PARMAREA(%r4) # our sccb
+       .insn rre,0xb2200000,%r2,%r1    # service call
+       ipm   %r1
+       srl   %r1,28                    # get cc code
+       xr    %r3, %r3
+       chi   %r1,3
+       be    .Lfchunk-.LPG1(%r13)      # leave
+       chi   %r1,2
+       be    .Lservicecall-.LPG1(%r13)
+       lpsw  .Lwaitsclp-.LPG1(%r13)
+.Lsclph:
+       lh    %r1,.Lsccbr-PARMAREA(%r4)
+       chi   %r1,0x10                  # 0x0010 is the sucess code
+       je    .Lprocsccb                # let's process the sccb
+       chi   %r1,0x1f0
+       bne   .Lfchunk-.LPG1(%r13)      # unhandled error code
+       c     %r2, .Lrcp-.LPG1(%r13)    # Did we try Read SCP forced
+       bne   .Lfchunk-.LPG1(%r13)      # if no, give up
+       l     %r2, .Lrcp2-.LPG1(%r13)   # try with Read SCP
+       b     .Lservicecall-.LPG1(%r13)
+.Lprocsccb:
+       lh    %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+       chi   %r1,0x00
+       jne   .Lscnd
+       l     %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one
+.Lscnd:
+       xr    %r3,%r3                   # same logic
+       ic    %r3,.Lscpa1-PARMAREA(%r4)
+       chi   %r3,0x00
+       jne   .Lcompmem
+       l     %r3,.Lscpa2-PARMAREA(%r13)
+.Lcompmem:
+       mr    %r2,%r1                   # mem in MB on 128-bit
+       l     %r1,.Lonemb-.LPG1(%r13)
+       mr    %r2,%r1                   # mem size in bytes in %r3
+       b     .Lfchunk-.LPG1(%r13)
+
+.Lpmask:
+       .byte 0
+.align 8
+.Lpcext:.long  0x00080000,0x80000000
+.Lcr:
+       .long 0x00                      # place holder for cr0
+.Lwaitsclp:
+       .long 0x020A0000
+       .long .Lsclph
+.Lrcp:
+       .int 0x00120001                 # Read SCP forced code
+.Lrcp2:
+       .int 0x00020001                 # Read SCP code
+.Lonemb:
+       .int 0x100000
+.Lfchunk:
+
 #
 # find memory chunks.
 #
+       lr    %r9,%r3                    # end of mem
        mvc   __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
        la    %r1,1                      # test in increments of 128KB
        sll   %r1,17
@@ -488,38 +559,46 @@ startup:basr  %r13,0                     # get base
        slr   %r4,%r4                    # set start of chunk to zero
        slr   %r5,%r5                    # set end of chunk to zero
        slr   %r6,%r6                    # set access code to zero
+       la    %r10, MEMORY_CHUNKS        # number of chunks
 .Lloop:
        tprot 0(%r5),0                   # test protection of first byte
        ipm   %r7
        srl   %r7,28
        clr   %r6,%r7                    # compare cc with last access code
        be    .Lsame-.LPG1(%r13)
-       clr   %r4,%r5                    # chunk size > 0?
-       be    .Lsize0-.LPG1(%r13)
-       st    %r4,0(%r3)                 # store start address of chunk
-       lr    %r0,%r5
-       slr   %r0,%r4
-       st    %r0,4(%r3)                 # store size of chunk
-       st    %r6,8(%r3)                 # store type of chunk
-       la    %r3,12(%r3)
-       lr    %r4,%r5                    # set start to end
-.Lsize0:
-       lr    %r6,%r7                    # set access code to last cc
+       b     .Lchkmem-.LPG1(%r13)
 .Lsame:
        ar    %r5,%r1                    # add 128KB to end of chunk
        bno   .Lloop-.LPG1(%r13)         # r1 < 0x80000000 -> loop
 .Lchkmem:                               # > 2GB or tprot got a program check
        clr   %r4,%r5                    # chunk size > 0?
-       be    .Ldonemem-.LPG1(%r13)
+       be    .Lchkloop-.LPG1(%r13)
        st    %r4,0(%r3)                 # store start address of chunk
        lr    %r0,%r5
        slr   %r0,%r4
        st    %r0,4(%r3)                 # store size of chunk
        st    %r6,8(%r3)                 # store type of chunk
+       la    %r3,12(%r3)
+       l     %r4,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
+       st    %r5,0(%r4)                 # store last end to memory size
+       ahi   %r10,-1                    # update chunk number
+.Lchkloop:
+       lr    %r6,%r7                    # set access code to last cc
+       # we got an exception or we're starting a new
+       # chunk , we must check if we should
+       # still try to find valid memory (if we detected
+       # the amount of available storage), and if we
+       # have chunks left
+       xr    %r0,%r0
+       clr   %r0,%r9                    # did we detect memory?
+       je    .Ldonemem                  # if not, leave
+       chi   %r10,0                     # do we have chunks left?
+       je    .Ldonemem
+       alr   %r5,%r1                    # add 128KB to end of chunk
+       lr    %r4,%r5                    # potential new chunk
+       clr    %r5,%r9                   # should we go on?
+       jl     .Lloop
 .Ldonemem:             
-        l     %r1,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
-       st    %r5,0(%r1)                 # store last end to memory size
-       
         l      %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
 #
 # find out if we are running under VM
@@ -631,6 +710,23 @@ _pstart:
        .byte  "root=/dev/ram0 ro"
         .byte  0
        .org   0x11000
+.Lsccb:
+       .hword 0x1000                   # length, one page
+       .byte 0x00,0x00,0x00
+       .byte 0x80                      # variable response bit set
+.Lsccbr:
+       .hword 0x00                     # response code
+.Lscpincr1:
+       .hword 0x00
+.Lscpa1:
+       .byte 0x00
+       .fill 89,1,0
+.Lscpa2:
+       .int 0x00
+.Lscpincr2:
+       .quad 0x00
+       .fill 3984,1,0
+       .org 0x12000
        .global _pend
 _pend: