/* * arch/s390/boot/ipldump.S * * S390 version * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), * * Tape dump ipl record. Put it on a tape and ipl from it and it will * write a dump of the real storage after the ipl record on that tape. */ #include #include #define IPL_BS 1024 .org 0 .long 0x00080000,0x80000000+_start # The first 24 bytes are loaded .long 0x07000000,0x60000001 # by ipl to addresses 0-23. .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 # svc old psw .long 0x00000000,0x00000000 # program check old psw .long 0x00000000,0x00000000 # machine check old psw .long 0x00000000,0x00000000 # io old psw .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x000a0000,0x00000058 # external new psw .long 0x000a0000,0x00000060 # svc new psw .long 0x000a0000,0x00000068 # program check new psw .long 0x000a0000,0x00000070 # machine check new psw .long 0x00080000,0x80000000+.Lioint # io new psw .org 0x100 .globl _start _start: l %r1,0xb8 # load ipl subchannel number # # find out memory size # mvc 104(8),.Lpcmem0 # setup program check handler slr %r3,%r3 lhi %r2,1 sll %r2,20 .Lloop0: l %r0,0(%r3) # test page ar %r3,%r2 # add 1M jnm .Lloop0 # r1 < 0x80000000 -> loop .Lchkmem0: n %r3,.L4malign0 # align to multiples of 4M st %r3,.Lmemsize # store memory size .Lmemok: # # first write a tape mark # bras %r14,.Ltapemark # # write real storage to tape # slr %r2,%r2 # start at address 0 bras %r14,.Lwriter # load ramdisk # # write another tape mark # bras %r14,.Ltapemark # # everything written, stop processor # lpsw .Lstopped # # subroutine for writing to tape # Paramters: # R1 = device number # R2 = start address # R3 = length .Lwriter: st %r14,.Lldret la %r12,.Lorbread # r12 = address of orb la %r5,.Lirb # r5 = address of irb st %r2,.Lccwwrite+4 # initialize CCW data addresses lctl %c6,%c6,.Lcr6 slr %r2,%r2 .Lldlp: lhi %r6,3 # 3 retries .Lssch: ssch 0(%r12) # write chunk of IPL_BS bytes jnz .Llderr .Lw4end: bras %r14,.Lwait4io tm 8(%r5),0x82 # do we have a problem ? jnz .Lrecov l %r0,.Lccwwrite+4 # update CCW data addresses ahi %r0,IPL_BS st %r0,.Lccwwrite+4 clr %r0,%r3 # enough ? jl .Lldlp .Ldone: l %r14,.Lldret br %r14 # r2 contains the total size .Lrecov: bras %r14,.Lsense # do the sensing brct %r6,.Lssch # dec. retry count & branch j .Llderr .Ltapemark: st %r14,.Lldret la %r12,.Lorbmark # r12 = address of orb la %r5,.Lirb # r5 = address of irb lctl %c6,%c6,.Lcr6 ssch 0(%r12) # write a tape mark jnz .Llderr bras %r14,.Lwait4io l %r14,.Lldret br %r14 # # Sense subroutine # .Lsense: st %r14,.Lsnsret la %r7,.Lorbsense ssch 0(%r7) # start sense command jnz .Llderr bras %r14,.Lwait4io l %r14,.Lsnsret tm 8(%r5),0x82 # do we have a problem ? jnz .Llderr br %r14 # # Wait for interrupt subroutine # .Lwait4io: lpsw .Lwaitpsw .Lioint: c %r1,0xb8 # compare subchannel number jne .Lwait4io tsch 0(%r5) slr %r0,%r0 tm 8(%r5),0x82 # do we have a problem ? jnz .Lwtexit tm 8(%r5),0x04 # got device end ? jz .Lwait4io .Lwtexit: br %r14 .Llderr: lpsw .Lcrash .align 8 .Lorbread: .long 0x00000000,0x0080ff00,.Lccwwrite .align 8 .Lorbsense: .long 0x00000000,0x0080ff00,.Lccwsense .align 8 .Lorbmark: .long 0x00000000,0x0080ff00,.Lccwmark .align 8 .Lccwwrite: .long 0x01200000+IPL_BS,0x00000000 .Lccwsense: .long 0x04200001,0x00000000 .Lccwmark: .long 0x1f200001,0x00000000 .Lwaitpsw: .long 0x020a0000,0x80000000+.Lioint .Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .Lcr6: .long 0xff000000 .align 8 .Lcrash:.long 0x000a0000,0x00000000 .Lstopped: .long 0x000a0000,0x00001234 .Lpcmem0:.long 0x00080000,0x80000000 + .Lchkmem0 .L4malign0:.long 0xffc00000 .Lmemsize:.long 0 .Lldret:.long 0 .Lsnsret: .long 0 .org IPL_BS