ipleckd.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #
  2. #  arch/s390/boot/ipleckd.S
  3. #    IPL record for 3380/3390 DASD
  4. #
  5. #  S390 version
  6. #    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  7. #    Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>
  8. #
  9. #
  10. # FIXME:  should use the countarea to determine the blocksize
  11. # FIXME:  should insert zeroes into memory when filling holes
  12. # FIXME:  calculate blkpertrack from rdc data and blksize
  13. # change 09/20/00       removed obsolete store of ipldevice to textesegment
  14. # Usage of registers
  15. # r1: ipl subchannel ( general use, dont overload without save/restore !)
  16. # r10:
  17. # r13: base register  index to 0x0000
  18. # r14: callers address
  19. # r15: temporary save register (we have no stack!)
  20. # storage layout:
  21. #include <asm/lowcore.h>
  22. .org 0
  23. .psw: .long 0x00080000,0x80000000+_start
  24. .ccw1: .long 0x06000000,0x00001000     # Re-Read enough of bootsector to start
  25. .ccw2: .long 0x00000000,0x00000000 # read countarea of record 1 to s/w.
  26. .org 0x58
  27. .Lextn: .long 0x000a0000,0x00000000+.Lextn
  28. .Lsvcn: .long 0x000a0000,0x00000000+.Lsvcn
  29. .Lprgn: .long 0x00080000,0x00000000+.Lecs
  30. .Lmcn: .long 0x000a0000,0x00000000+.Lmcn
  31. .Lion: .long   0x00080000,0x80000000+.Lionewaddr
  32. .org 0xe0
  33. .Llstad:.long  0x00000000,0x00000000 # sectorno + ct of bootlist
  34. .org 0xf0 # Lets start now...
  35. _start: .globl _start
  36. l   %r1,__LC_SUBCHANNEL_ID # get IPL-subchannel from lowcore
  37. st %r1,__LC_IPLDEV         # keep it for reipl
  38. stsch .Lrdcdata
  39. oi      .Lrdcdata+5,0x84        # enable ssch and multipath mode
  40. .Lecs:  xi .Lrdcdata+27,0x01 # enable concurrent sense
  41. msch .Lrdcdata
  42.         xi      .Lprgn,6                # restore Wait and d/a bit in PCnew PSW
  43. l %r2,.Lparm
  44. mvc     0x0(8,%r2),.Lnull       # set parmarea to null
  45. lctl %c6,%c6,.Lc6      # enable all interrupts
  46. .Lrdc: # read device characteristics
  47. la %r6,.Lrdcccw     
  48. st      %r6,.Lorb+8 # store cp-address to orb
  49. bras    %r15,.Lssch # start I/O
  50. oi .Llodata+1,0x80
  51. lh %r5,.Lcountarea+6 # init r5 from countarea
  52. stcm %r5,3,.Lrdccw+2 # and store into rd template *FIXME*
  53. stcm %r5,3,.Llodata+14 # and store into lodata *FIXME*
  54. .Lbootlist:
  55. l %r2,.Llstad
  56. l %r3,.Lblklst     
  57. lhi %r4,1
  58. bras %r14,.Lreadblks
  59. .Lloader:
  60. l %r10,.Lblklst      # r10 is index to bootlist
  61. lhi %r5,4 # r5: skip 4 blocks = firstpage....
  62. .Lkloop:
  63. clc .Lnull(8),0(%r10) # test blocklist
  64. jz .Lchkparm # end of list?
  65. l %r2,0(%r10) # get startblock to r2
  66. slr %r4,%r4 # erase r4
  67. icm %r4,1,7(%r10) # get blockcount
  68. slr %r3,%r3 # get address to r3
  69. icm  %r3,0xe,4(%r10)
  70. chi %r5,0 # still blocks to skip?
  71. jz .Ldoread # no: start reading
  72. cr %r5,%r4 # #skipblocks >= blockct?
  73. jm .L007 # no: skip the blocks one by one
  74. .L006:
  75. sr %r5,%r4 # decrease number of blocks to skip
  76. j .Lkcont # advance to next entry
  77. .L007:
  78. ahi %r2,1 # skip 1 block...
  79. bctr    %r4,0                   # update blockct
  80. ah %r3,.Lcountarea+6       # increment address
  81. bct %r5,.L007 # 4 blocks skipped?
  82. .Ldoread:
  83. ltr %r2,%r2 # test startblock
  84. jz .Lzeroes # startblocks is zero (hole)
  85. .Ldiskread:
  86. bras %r14,.Lreadblks
  87. j .Lkcont
  88. .Lzeroes:
  89. lr %r2,%r3
  90. .L001: slr %r3,%r3
  91. icm %r3,3,.Lcountarea+6     # get blocksize
  92. slr %r5,%r5 # no bytes to move
  93. .L008: mvcle %r2,%r4,0    # fill zeroes to storage
  94. jo .L008 # until block is filled
  95. brct %r4,.L001    # skip to next block
  96. .Lkcont:
  97. ahi %r10,8
  98. j .Lkloop
  99. .Lchkparm:
  100. lm %r3,%r4,.Lstart         # load .Lstart and .Lparm
  101. clc 0x0(4,%r4),.Lnull     
  102. je .Lrunkern
  103. mvc 0x480(128,%r3),0(%r4) # move 1k-0x80 to parmarea
  104. mvc 0x500(256,%r3),0x80(%r4)
  105. mvc 0x600(256,%r3),0x180(%r4)
  106. mvc 0x700(256,%r3),0x280(%r4)
  107. .Lrunkern:
  108. # lhi %r2,17
  109. # sll %r2,12
  110. # st %r1,0xc6c(%r2) # store iplsubchannel to lowcore
  111. # st %r1,0xc6c # store iplsubchannel to lowcore
  112. br %r3
  113. # This function does the start IO
  114. # r2: number of first block to read ( input by caller )
  115. # r3: address to read data to ( input by caller )
  116. # r4: number of blocks to read ( input by caller )
  117. # r5: destroyed
  118. # r6: blocks per track ( input by caller )
  119. # r7: number of heads 
  120. # r8:
  121. # r9:
  122. # r10:
  123. # r11: temporary register
  124. # r12: local use for base address
  125. # r13: base address for module
  126. # r14: address of caller for subroutine
  127. # r15: temporary save register (since we have no stack)
  128. .Lreadblks:
  129. la %r12,.Ldeccw     
  130. st %r12,8+.Lorb # store cpaddr to orb
  131. ahi %r12,0x10 # increment r12 to point to rdccw
  132. oi 1(%r12),0x40 # set CC in rd template
  133. # first setup the read CCWs
  134. lr %r15,%r4 # save number or blocks
  135. slr %r7,%r7
  136. icm %r7,3,.Lrdcdata+14      # load heads to r7
  137. lhi     %r6,9
  138. clc     .Lrdcdata+3(2),.L9345
  139. je .L011
  140. lhi %r6,10
  141. clc .Lrdcdata+3(2),.L3380
  142. je .L011
  143. lhi %r6,12
  144. clc .Lrdcdata+3(2),.L3390     
  145. je .L011
  146.         bras  %r14,.Ldisab
  147. .L011:
  148. # loop for nbl times
  149. .Lrdloop:
  150. mvc 0(8,%r12),.Lrdccw      # copy template to this ccw
  151. st %r3,4(%r12) # store target address to this ccw
  152. bct %r4,.L005 # decrement no of blks still to do
  153. ni 1(%r12),0x3f # delete CC from last ccw
  154. lr %r4,%r15 # restore number of blocks
  155. # read CCWs are setup now
  156. stcm %r4,3,.Llodata+2      # store blockno to lodata clears r4
  157. ar %r4,%r2 # r4 (clear): ebl = blk + nbl
  158. bctr    %r4,0 # decrement r4 ( last blk touched 
  159. srda %r2,32 # trk = blk / bpt, bot = blk % bpt 
  160. dr %r2,%r6 # r3: trk, r2: bot
  161. ahi %r2,1 # bot++ ( we start counting at 1 )
  162. stcm %r2,1,.Llodata+12      # store bot to lodata
  163. xr  %r2,%r2 # cy  = trk / heads, hd  = trk % heads
  164. dr %r2,%r7 # r3: cy, r2: hd
  165. sll %r3,16 # combine to CCHH in r3
  166. or %r3,%r2
  167. st %r3,.Ldedata+8      # store cchh to dedata
  168. st %r3,.Llodata+4      # store cchh to lodata
  169. st %r3,.Llodata+8      # store cchh to lodata
  170. lr %r15,%r5 # save r5
  171. srda %r4,32 # tr2 = ebl / bpt
  172. dr %r4,%r6 # r5: tr2, r4: bot2
  173. xr  %r4,%r4 # cy2 = tr2 / heads, hd2 = hd2 % heads
  174. dr %r4,%r7 # r5: cy2, r4: hd2 
  175. stcm %r5,3,.Ldedata+12      # store cy2,hd2 to dedata
  176. stcm %r4,3,.Ldedata+14      # store cy2,hd2 to dedata
  177. lr %r5,%r15 # restore r5
  178. # CCWs are setup now, arent they?
  179. bras %r15,.Lssch # start I/O
  180. br %r14 # return to caller
  181. .L005:
  182. ah  %r3,.Lcountarea+6      # add blocksize to target address
  183. ahi %r12,8 # add sizeof(ccw) to base address
  184. j .Lrdloop
  185. # end of function
  186. # This function does the start IO
  187. # r1: Subchannel number
  188. # r8: ORB address
  189. # r9: IRB address
  190. .Lssch:
  191. lhi     %r13,10 # initialize retries
  192. .L012:
  193. ssch .Lorb # start I/O
  194. jz .Ltpi # ok?
  195. bras %r14,.Ldisab # error
  196. .Ltpi:
  197. lpsw .Lwaitpsw      # load wait-PSW
  198. .Lionewaddr:
  199. c %r1,0xb8      # compare to ipl subhchannel
  200. jnz .Ltpi # not equal: loop
  201. clc 0xbc(4),.Lorb  # cross check the intparm
  202. jnz .Ltpi                # not equal: loop 
  203. tsch    .Lirb # get status
  204. tm .Lirb+9,0xff # channel status ?
  205. jz .L003 # CS == 0x00
  206. bras %r14,.Ldisab # error
  207. .L003:
  208. tm .Lirb+8,0xf3 # DS different from CE/DE
  209. jz .L004 # ok ?
  210. bct %r13,.L012 # retries <= 5 ?
  211. bras %r14,.Ldisab # error
  212. .L004:
  213. tm .Lirb+8,0x04 # DE set?
  214. jz .Ltpi # DE not set, loop
  215. .Lsschend:
  216. br %r15 # return to caller
  217. # end of function
  218. # In case of error goto disabled wait with %r14 containing the caller
  219. .Ldisab:
  220. st %r14,.Ldisabpsw+4     
  221. lpsw .Ldisabpsw     
  222. # FIXME pre-initialized data should be listed first
  223. # NULLed storage can be taken from anywhere ;) 
  224. .Lblklst:
  225. .long   0x00002000     
  226. .align 8
  227. .Ldisabpsw: 
  228. .long 0x000a0000,0x00000000
  229. .Lwaitpsw:
  230. .long 0x020a0000,0x00000000+.Ltpi
  231. .Lorb:
  232. .long 0x0049504c,0x0080ff00 # intparm is " IPL"
  233. .Lc6: .long 0xff000000
  234. .Lstart:
  235. .long 0x00010000              # do not separate .Lstart and .Lparm
  236. .Lparm:
  237. .long 0x00008000              # they are loaded with a LM
  238. .L3390:
  239. .word  0x3390
  240. .L9345:
  241. .word 0x9345
  242. .L3380:
  243. .word 0x3380
  244. .Lnull:
  245. .long 0x00000000,0x00000000
  246. .align 4
  247. .Lrdcdata:
  248. .long 0x00000000,0x00000000
  249. .long 0x00000000,0x00000000
  250. .long 0x00000000,0x00000000
  251. .long 0x00000000,0x00000000
  252. .long 0x00000000,0x00000000
  253. .long 0x00000000,0x00000000
  254. .long 0x00000000,0x00000000
  255. .long 0x00000000,0x00000000
  256. .Lirb:
  257. .long 0x00000000,0x00000000
  258. .long 0x00000000,0x00000000
  259. .long 0x00000000,0x00000000
  260. .long 0x00000000,0x00000000
  261. .long 0x00000000,0x00000000
  262. .long 0x00000000,0x00000000
  263. .long 0x00000000,0x00000000
  264. .long 0x00000000,0x00000000
  265. .Lcountarea:
  266. .word 0x0000 # cyl;
  267. .word 0x0000 # head;
  268. .byte 0x00 # record;
  269. .byte 0x00 # key length;
  270. .word 0x0000 # data length == blocksize;
  271. .Ldedata:
  272. .long 0x40c00000,0x00000000
  273. .long 0x00000000,0x00000000
  274. .Llodata:
  275. .long 0x06000001,0x00000000
  276. .long 0x00000000,0x01000000
  277. .long 0x12345678
  278. .org 0x7c8
  279. .Lrdcccw: # CCW read device characteristics
  280. .long 0x64400040,0x00000000+.Lrdcdata
  281. .long 0x63400010,0x00000000+.Ldedata
  282. .long 0x47400010,0x00000000+.Llodata
  283. .long 0x12000008,0x00000000+.Lcountarea
  284. .Ldeccw:
  285. .long 0x63400010,0x00000000+.Ldedata
  286. .Lloccw:
  287. .long 0x47400010,0x00000000+.Llodata
  288. .Lrdccw:
  289. .long 0x86400000,0x00000000
  290. .org 0x800
  291. # end of pre initialized data is here CCWarea follows
  292. # from here we load 1k blocklist 
  293. # end of function