[S390] Convert memory detection into C code.
Hopefully this will make it more maintainable and less error prone. Code makes use of search_exception_tables(). Since it calls this function before the kernel exeception table is sorted, there is an early call to sort_main_extable(). This way it's easy to use the already present infrastructure of fixup sections. Also this would allows to easily convert the rest of head[31|64].S into C code. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
31ee4b2f40
commit
ab14de6c37
@@ -65,162 +65,6 @@ startup_continue:
|
||||
brasl %r14,startup_init
|
||||
# set program check new psw mask
|
||||
mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
|
||||
larl %r1,.Lslowmemdetect # set program check address
|
||||
stg %r1,__LC_PGM_NEW_PSW+8
|
||||
lghi %r1,0xc
|
||||
diag %r0,%r1,0x260 # get memory size of virtual machine
|
||||
cgr %r0,%r1 # different? -> old detection routine
|
||||
jne .Lslowmemdetect
|
||||
larl %r3,ipl_flags
|
||||
llgt %r3,0(%r3)
|
||||
chi %r3,4 # ipled from an kernel NSS
|
||||
je .Lslowmemdetect
|
||||
aghi %r1,1 # size is one more than end
|
||||
larl %r2,memory_chunk
|
||||
stg %r1,8(%r2) # store size of chunk
|
||||
|
||||
.Lslowmemdetect:
|
||||
l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
|
||||
.Lservicecall:
|
||||
stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
|
||||
|
||||
stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0
|
||||
la %r1,0x200 # set bit 22
|
||||
og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
|
||||
stg %r1,.Lcr-.LPG1(%r13)
|
||||
lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0
|
||||
|
||||
mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw
|
||||
larl %r1,.Lsclph
|
||||
stg %r1,__LC_EXT_NEW_PSW+8 # set handler
|
||||
|
||||
larl %r4,.Lsccb # %r4 is our index for sccb stuff
|
||||
lgr %r1,%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)
|
||||
lpswe .Lwaitsclp-.LPG1(%r13)
|
||||
.Lsclph:
|
||||
lh %r1,.Lsccbr-.Lsccb(%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:
|
||||
lghi %r1,0
|
||||
icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0
|
||||
jnz .Lscnd
|
||||
lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one
|
||||
.Lscnd:
|
||||
xr %r3,%r3 # same logic
|
||||
ic %r3,.Lscpa1-.Lsccb(%r4)
|
||||
chi %r3,0x00
|
||||
jne .Lcompmem
|
||||
l %r3,.Lscpa2-.Lsccb(%r4)
|
||||
.Lcompmem:
|
||||
mlgr %r2,%r1 # mem in MB on 128-bit
|
||||
l %r1,.Lonemb-.LPG1(%r13)
|
||||
mlgr %r2,%r1 # mem size in bytes in %r3
|
||||
b .Lfchunk-.LPG1(%r13)
|
||||
|
||||
.align 4
|
||||
.Lpmask:
|
||||
.byte 0
|
||||
.align 8
|
||||
.Lcr:
|
||||
.quad 0x00 # place holder for cr0
|
||||
.Lwaitsclp:
|
||||
.quad 0x0102000180000000,.Lsclph
|
||||
.Lrcp:
|
||||
.int 0x00120001 # Read SCP forced code
|
||||
.Lrcp2:
|
||||
.int 0x00020001 # Read SCP code
|
||||
.Lonemb:
|
||||
.int 0x100000
|
||||
|
||||
.Lfchunk:
|
||||
|
||||
#
|
||||
# find memory chunks.
|
||||
#
|
||||
larl %r9,memory_chunk # skip tprot loop if diag260
|
||||
lg %r9,8(%r9) # memory detection was successful
|
||||
ltgr %r9,%r9
|
||||
jne .Ldonemem
|
||||
|
||||
lgr %r9,%r3 # end of mem
|
||||
larl %r1,.Lchkmem # set program check address
|
||||
stg %r1,__LC_PGM_NEW_PSW+8
|
||||
la %r1,1 # test in increments of 128KB
|
||||
sllg %r1,%r1,17
|
||||
larl %r3,memory_chunk
|
||||
slgr %r4,%r4 # set start of chunk to zero
|
||||
slgr %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
|
||||
je .Lsame
|
||||
lghi %r8,0 # no program checks
|
||||
j .Lsavchk
|
||||
.Lsame:
|
||||
algr %r5,%r1 # add 128KB to end of chunk
|
||||
# no need to check here,
|
||||
brc 12,.Lloop # this is the same chunk
|
||||
.Lchkmem: # > 16EB or tprot got a program check
|
||||
lghi %r8,1 # set program check flag
|
||||
.Lsavchk:
|
||||
clgr %r4,%r5 # chunk size > 0?
|
||||
je .Lchkloop
|
||||
stg %r4,0(%r3) # store start address of chunk
|
||||
lgr %r0,%r5
|
||||
slgr %r0,%r4
|
||||
stg %r0,8(%r3) # store size of chunk
|
||||
st %r6,20(%r3) # store type of chunk
|
||||
la %r3,24(%r3)
|
||||
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
|
||||
lghi %r4,1
|
||||
sllg %r4,%r4,31
|
||||
clgr %r5,%r4
|
||||
je .Lhsaskip
|
||||
xr %r0, %r0
|
||||
clgr %r0, %r9 # did we detect memory?
|
||||
je .Ldonemem # if not, leave
|
||||
chi %r10, 0 # do we have chunks left?
|
||||
je .Ldonemem
|
||||
.Lhsaskip:
|
||||
chi %r8,1 # program check ?
|
||||
je .Lpgmchk
|
||||
lgr %r4,%r5 # potential new chunk
|
||||
algr %r5,%r1 # add 128KB to end of chunk
|
||||
j .Llpcnt
|
||||
.Lpgmchk:
|
||||
algr %r5,%r1 # add 128KB to end of chunk
|
||||
lgr %r4,%r5 # potential new chunk
|
||||
.Llpcnt:
|
||||
clgr %r5,%r9 # should we go on?
|
||||
jl .Lloop
|
||||
.Ldonemem:
|
||||
|
||||
larl %r12,machine_flags
|
||||
#
|
||||
# find out if we have the MVPG instruction
|
||||
@@ -324,25 +168,6 @@ ipl_devno:
|
||||
.word 0
|
||||
|
||||
.org 0x12000
|
||||
.globl s390_readinfo_sccb
|
||||
s390_readinfo_sccb:
|
||||
.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 0x13000
|
||||
|
||||
#ifdef CONFIG_SHARED_KERNEL
|
||||
.org 0x100000
|
||||
|
Reference in New Issue
Block a user