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
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
.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: