/*1* Mini SCLP driver.2*3* Copyright IBM Corp. 2004,20094*5* Author(s): Peter Oberparleiter <[email protected]>,6* Heiko Carstens <[email protected]>,7*8*/910LC_EXT_NEW_PSW = 0x58 # addr of ext int handler11LC_EXT_NEW_PSW_64 = 0x1b0 # addr of ext int handler 64 bit12LC_EXT_INT_PARAM = 0x80 # addr of ext int parameter13LC_EXT_INT_CODE = 0x86 # addr of ext int code14LC_AR_MODE_ID = 0xa31516#17# Subroutine which waits synchronously until either an external interruption18# or a timeout occurs.19#20# Parameters:21# R2 = 0 for no timeout, non-zero for timeout in (approximated) seconds22#23# Returns:24# R2 = 0 on interrupt, 2 on timeout25# R3 = external interruption parameter if R2=026#2728_sclp_wait_int:29stm %r6,%r15,24(%r15) # save registers30basr %r13,0 # get base register31.LbaseS1:32ahi %r15,-96 # create stack frame33la %r8,LC_EXT_NEW_PSW # register int handler34la %r9,.LextpswS1-.LbaseS1(%r13)35#ifdef CONFIG_64BIT36tm LC_AR_MODE_ID,137jno .Lesa138la %r8,LC_EXT_NEW_PSW_64 # register int handler 64 bit39la %r9,.LextpswS1_64-.LbaseS1(%r13)40.Lesa1:41#endif42mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8)43mvc 0(16,%r8),0(%r9)44lhi %r6,0x0200 # cr mask for ext int (cr0.54)45ltr %r2,%r246jz .LsetctS147ahi %r6,0x0800 # cr mask for clock int (cr0.52)48stck .LtimeS1-.LbaseS1(%r13) # initiate timeout49al %r2,.LtimeS1-.LbaseS1(%r13)50st %r2,.LtimeS1-.LbaseS1(%r13)51sckc .LtimeS1-.LbaseS1(%r13)5253.LsetctS1:54stctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # enable required interrupts55l %r0,.LctlS1-.LbaseS1(%r13)56lhi %r1,~(0x200 | 0x800) # clear old values57nr %r1,%r058or %r1,%r6 # set new value59st %r1,.LctlS1-.LbaseS1(%r13)60lctl %c0,%c0,.LctlS1-.LbaseS1(%r13)61st %r0,.LctlS1-.LbaseS1(%r13)62lhi %r2,2 # return code for timeout63.LloopS1:64lpsw .LwaitpswS1-.LbaseS1(%r13) # wait until interrupt65.LwaitS1:66lh %r7,LC_EXT_INT_CODE67chi %r7,0x1004 # timeout?68je .LtimeoutS169chi %r7,0x2401 # service int?70jne .LloopS171sr %r2,%r272l %r3,LC_EXT_INT_PARAM73.LtimeoutS1:74lctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # restore interrupt setting75# restore old handler76mvc 0(16,%r8),.LoldpswS1-.LbaseS1(%r13)77lm %r6,%r15,120(%r15) # restore registers78br %r14 # return to caller7980.align 881.LoldpswS1:82.long 0, 0, 0, 0 # old ext int PSW83.LextpswS1:84.long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int85#ifdef CONFIG_64BIT86.LextpswS1_64:87.quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit88#endif89.LwaitpswS1:90.long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int91.LtimeS1:92.quad 0 # current time93.LctlS1:94.long 0 # CT0 contents9596#97# Subroutine to synchronously issue a service call.98#99# Parameters:100# R2 = command word101# R3 = sccb address102#103# Returns:104# R2 = 0 on success, 1 on failure105# R3 = sccb response code if R2 = 0106#107108_sclp_servc:109stm %r6,%r15,24(%r15) # save registers110ahi %r15,-96 # create stack frame111lr %r6,%r2 # save command word112lr %r7,%r3 # save sccb address113.LretryS2:114lhi %r2,1 # error return code115.insn rre,0xb2200000,%r6,%r7 # servc116brc 1,.LendS2 # exit if not operational117brc 8,.LnotbusyS2 # go on if not busy118sr %r2,%r2 # wait until no longer busy119bras %r14,_sclp_wait_int120j .LretryS2 # retry121.LnotbusyS2:122sr %r2,%r2 # wait until result123bras %r14,_sclp_wait_int124sr %r2,%r2125lh %r3,6(%r7)126.LendS2:127lm %r6,%r15,120(%r15) # restore registers128br %r14129130#131# Subroutine to set up the SCLP interface.132#133# Parameters:134# R2 = 0 to activate, non-zero to deactivate135#136# Returns:137# R2 = 0 on success, non-zero on failure138#139140_sclp_setup:141stm %r6,%r15,24(%r15) # save registers142ahi %r15,-96 # create stack frame143basr %r13,0 # get base register144.LbaseS3:145l %r6,.LsccbS0-.LbaseS3(%r13) # prepare init mask sccb146mvc 0(.LinitendS3-.LinitsccbS3,%r6),.LinitsccbS3-.LbaseS3(%r13)147ltr %r2,%r2 # initialization?148jz .LdoinitS3 # go ahead149# clear masks150xc .LinitmaskS3-.LinitsccbS3(8,%r6),.LinitmaskS3-.LinitsccbS3(%r6)151.LdoinitS3:152l %r2,.LwritemaskS3-.LbaseS3(%r13)# get command word153lr %r3,%r6 # get sccb address154bras %r14,_sclp_servc # issue service call155ltr %r2,%r2 # servc successful?156jnz .LerrorS3157chi %r3,0x20 # write mask successful?158jne .LerrorS3159# check masks160la %r2,.LinitmaskS3-.LinitsccbS3(%r6)161l %r1,0(%r2) # receive mask ok?162n %r1,12(%r2)163cl %r1,0(%r2)164jne .LerrorS3165l %r1,4(%r2) # send mask ok?166n %r1,8(%r2)167cl %r1,4(%r2)168sr %r2,%r2169je .LendS3170.LerrorS3:171lhi %r2,1 # error return code172.LendS3:173lm %r6,%r15,120(%r15) # restore registers174br %r14175.LwritemaskS3:176.long 0x00780005 # SCLP command for write mask177.LinitsccbS3:178.word .LinitendS3-.LinitsccbS3179.byte 0,0,0,0180.word 0181.word 0182.word 4183.LinitmaskS3:184.long 0x80000000185.long 0x40000000186.long 0187.long 0188.LinitendS3:189190#191# Subroutine which prints a given text to the SCLP console.192#193# Parameters:194# R2 = address of nil-terminated ASCII text195#196# Returns:197# R2 = 0 on success, 1 on failure198#199200_sclp_print:201stm %r6,%r15,24(%r15) # save registers202ahi %r15,-96 # create stack frame203basr %r13,0 # get base register204.LbaseS4:205l %r8,.LsccbS0-.LbaseS4(%r13) # prepare write data sccb206mvc 0(.LmtoS4-.LwritesccbS4,%r8),.LwritesccbS4-.LbaseS4(%r13)207la %r7,.LmtoS4-.LwritesccbS4(%r8) # current mto addr208sr %r0,%r0209l %r10,.Lascebc-.LbaseS4(%r13) # address of translation table210.LinitmtoS4:211# initialize mto212mvc 0(.LmtoendS4-.LmtoS4,%r7),.LmtoS4-.LbaseS4(%r13)213lhi %r6,.LmtoendS4-.LmtoS4 # current mto length214.LloopS4:215ic %r0,0(%r2) # get character216ahi %r2,1217ltr %r0,%r0 # end of string?218jz .LfinalizemtoS4219chi %r0,0x15 # end of line (NL)?220jz .LfinalizemtoS4221stc %r0,0(%r6,%r7) # copy to mto222la %r11,0(%r6,%r7)223tr 0(1,%r11),0(%r10) # translate to EBCDIC224ahi %r6,1225j .LloopS4226.LfinalizemtoS4:227sth %r6,0(%r7) # update mto length228lh %r9,.LmdbS4-.LwritesccbS4(%r8) # update mdb length229ar %r9,%r6230sth %r9,.LmdbS4-.LwritesccbS4(%r8)231lh %r9,.LevbufS4-.LwritesccbS4(%r8)# update evbuf length232ar %r9,%r6233sth %r9,.LevbufS4-.LwritesccbS4(%r8)234lh %r9,0(%r8) # update sccb length235ar %r9,%r6236sth %r9,0(%r8)237ar %r7,%r6 # update current mto address238ltr %r0,%r0 # more characters?239jnz .LinitmtoS4240l %r2,.LwritedataS4-.LbaseS4(%r13)# write data241lr %r3,%r8242bras %r14,_sclp_servc243ltr %r2,%r2 # servc successful?244jnz .LendS4245chi %r3,0x20 # write data successful?246je .LendS4247lhi %r2,1 # error return code248.LendS4:249lm %r6,%r15,120(%r15) # restore registers250br %r14251252#253# Function which prints a given text to the SCLP console.254#255# Parameters:256# R2 = address of nil-terminated ASCII text257#258# Returns:259# R2 = 0 on success, 1 on failure260#261262.globl _sclp_print_early263_sclp_print_early:264stm %r6,%r15,24(%r15) # save registers265ahi %r15,-96 # create stack frame266#ifdef CONFIG_64BIT267tm LC_AR_MODE_ID,1268jno .Lesa2269ahi %r15,-80270stmh %r6,%r15,96(%r15) # store upper register halves271.Lesa2:272#endif273lr %r10,%r2 # save string pointer274lhi %r2,0275bras %r14,_sclp_setup # enable console276ltr %r2,%r2277jnz .LendS5278lr %r2,%r10279bras %r14,_sclp_print # print string280ltr %r2,%r2281jnz .LendS5282lhi %r2,1283bras %r14,_sclp_setup # disable console284.LendS5:285#ifdef CONFIG_64BIT286tm LC_AR_MODE_ID,1287jno .Lesa3288lmh %r6,%r15,96(%r15) # store upper register halves289ahi %r15,80290.Lesa3:291#endif292lm %r6,%r15,120(%r15) # restore registers293br %r14294295.LwritedataS4:296.long 0x00760005 # SCLP command for write data297.LwritesccbS4:298# sccb299.word .LmtoS4-.LwritesccbS4300.byte 0301.byte 0,0,0302.word 0303304# evbuf305.LevbufS4:306.word .LmtoS4-.LevbufS4307.byte 0x02308.byte 0309.word 0310311.LmdbS4:312# mdb313.word .LmtoS4-.LmdbS4314.word 1315.long 0xd4c4c240316.long 1317318# go319.LgoS4:320.word .LmtoS4-.LgoS4321.word 1322.long 0323.byte 0,0,0,0,0,0,0,0324.byte 0,0,0325.byte 0326.byte 0,0,0,0,0,0,0327.byte 0328.word 0329.byte 0,0,0,0,0,0,0,0,0,0330.byte 0,0,0,0,0,0,0,0331.byte 0,0,0,0,0,0,0,0332333.LmtoS4:334.word .LmtoendS4-.LmtoS4335.word 4336.word 0x1000337.byte 0338.byte 0,0,0339.LmtoendS4:340341# Global constants342.LsccbS0:343.long _sclp_work_area344.Lascebc:345.long _ascebc346347.section .data,"aw",@progbits348.balign 4096349_sclp_work_area:350.fill 4096351.previous352353354