1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
#
# Second stage boot loader for ckd/eckd devices.
# Copyright IBM Corp. 2001, 2006.
# Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
# Antoinette Kaschner (anto@de.ibm.com),
#
# An ckd/eckd loadlist entry is 8 bytes in length and contains 3 entries:
# offset 0 : C C H H R ( cyl head record )
# offset 5 : record length (16 bit)
# offset 7 : number of records(8 bit)
STAGE2_DESC = 0x218
#include "common.S"
# expand the common start code from iplcommon.s
stage2_start
# expand blocklist traversing code from iplcommon.s
blocklist_traverser
#
# expand enable/disable routines
device_fn
# parameter
# %r2+%r3: blocklist descriptor
# returns
# %r2 : number of bytes (blocksize * number of blocks)
_extract_length:
lr %r2,%r3
sll %r2,8
srl %r2,16
sll %r3,24
srl %r3,24
la %r3,1(%r3)
msr %r2,%r3
br %r14
# parameter
# %r2+%r3: blocklist descriptor
# returns
# %r2 : == 0 for normal block descriptor
# != 0 for zero block descriptor
_is_zero_block:
srl %r3,24
or %r2,%r3
br %r14
# parameter
# %r2+%r3: recordlist descriptor CCHHRLLn
# %r4 : device subchannel id
# %r5 : load address
_load_direct:
stm %r6,%r15,24(%r15) # save callers register
basr %r13,0 # base register
.Lbase:
s %r15,.Lc96-.Lbase(%r13) # new save area address
lr %r12,%r5 # save load address
lr %r11,%r4 # save subchannel id
stm %r2,%r3,.Lsearch-.Lbase(%r13) # get listdescriptor into search argument
slr %r10,%r10 # clear reg 10
icm %r10,1,.Lsearch+7-.Lbase(%r13) # get record number
la %r10,1(%r10) # add 1 to prevent negative value
slr %r9,%r9 # clear reg 9
icm %r9,3,.Lsearch+5-.Lbase(%r13) # get record size
sth %r9,.Lread+2-.Lbase(%r13) # store record size in read ccb
l %r1,.Lprd-.Lbase(%r13) # load address of ccw area
mvc 0(24,%r1),.Lccws-.Lbase(%r13) # copy seek/search/tic ccws to chain
la %r8,8(%r1) # get address of search command
st %r8,20(%r1) # store search address in tic
la %r1,24(%r1) # advance ccw chain pointer
slr %r3,%r3
b .Llpst-.Lbase(%r13)
.Lloop:
oi 1(%r1),0x40 # set command chain bit
la %r1,8(%r1) # update ccw pointer
.Llpst:
mvc 0(8,%r1),.Lread-.Lbase(%r13) # copy read ccw to chain
st %r12,4(,%r1) # store load address to read ccw
alr %r12,%r9 # add record size to load address
bct %r10,.Lloop-.Lbase(%r13)
ni 1(%r1),0xbf # clear command chain bit
la %r3,.Lorb-.Lbase(%r13) # pass address of orb
la %r4,.Lirb-.Lbase(%r13) # and pass address of irb
lr %r2,%r11 # pass subchannel id
bas %r14,_ssch-.Lbase(%r13) # read records
.Lexit:
lr %r2,%r12 # return updated load address
lm %r6,%r15,120(%r15)
br %r14
.Lc1: .long 1
.Lc96: .long 96
.Lc65535:
.long 65535
.Lprd: .long 0x4000
.align 8
.Lccws:
.long 0x07600006,0x00000000+.Lseekarg # seek for CYL and TRK
.Lsrch:
.long 0x31600005,0x00000000+.Lsearch # search for record
.long 0x08000000,0x00000000 # tic
.Lread:
.long 0x86200000,0x00000000 # read record into storage
.Lseekarg:
.word 0x0000 # seek argument
# format 00CCHH
.Lsearch:
.long 0x00000000,0x00000000 # search argument
# format CCHHRLLn
.align 8
.Lirb: .fill 64,1,0
.Lorb: .long 0x00000000,0x0080ff00,0x4000,0
# expand io subroutines from iplcommon.s
io_subroutines
# boot menu parameter area follows
menu_param_area
|