Loading...
Note: File does not exist in v6.8.
1/*
2 * Mini SCLP driver.
3 *
4 * Copyright IBM Corp. 2004, 2009
5 *
6 * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>,
7 * Heiko Carstens <heiko.carstens@de.ibm.com>,
8 *
9 */
10
11#include <linux/linkage.h>
12#include <asm/irq.h>
13
14LC_EXT_NEW_PSW = 0x58 # addr of ext int handler
15LC_EXT_NEW_PSW_64 = 0x1b0 # addr of ext int handler 64 bit
16LC_EXT_INT_PARAM = 0x80 # addr of ext int parameter
17LC_EXT_INT_CODE = 0x86 # addr of ext int code
18LC_AR_MODE_ID = 0xa3
19
20#
21# Subroutine which waits synchronously until either an external interruption
22# or a timeout occurs.
23#
24# Parameters:
25# R2 = 0 for no timeout, non-zero for timeout in (approximated) seconds
26#
27# Returns:
28# R2 = 0 on interrupt, 2 on timeout
29# R3 = external interruption parameter if R2=0
30#
31
32_sclp_wait_int:
33 stm %r6,%r15,24(%r15) # save registers
34 basr %r13,0 # get base register
35.LbaseS1:
36 ahi %r15,-96 # create stack frame
37 la %r8,LC_EXT_NEW_PSW # register int handler
38 la %r9,.LextpswS1-.LbaseS1(%r13)
39#ifdef CONFIG_64BIT
40 tm LC_AR_MODE_ID,1
41 jno .Lesa1
42 la %r8,LC_EXT_NEW_PSW_64 # register int handler 64 bit
43 la %r9,.LextpswS1_64-.LbaseS1(%r13)
44.Lesa1:
45#endif
46 mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8)
47 mvc 0(16,%r8),0(%r9)
48#ifdef CONFIG_64BIT
49 epsw %r6,%r7 # set current addressing mode
50 nill %r6,0x1 # in new psw (31 or 64 bit mode)
51 nilh %r7,0x8000
52 stm %r6,%r7,0(%r8)
53#endif
54 lhi %r6,0x0200 # cr mask for ext int (cr0.54)
55 ltr %r2,%r2
56 jz .LsetctS1
57 ahi %r6,0x0800 # cr mask for clock int (cr0.52)
58 stck .LtimeS1-.LbaseS1(%r13) # initiate timeout
59 al %r2,.LtimeS1-.LbaseS1(%r13)
60 st %r2,.LtimeS1-.LbaseS1(%r13)
61 sckc .LtimeS1-.LbaseS1(%r13)
62
63.LsetctS1:
64 stctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # enable required interrupts
65 l %r0,.LctlS1-.LbaseS1(%r13)
66 lhi %r1,~(0x200 | 0x800) # clear old values
67 nr %r1,%r0
68 or %r1,%r6 # set new value
69 st %r1,.LctlS1-.LbaseS1(%r13)
70 lctl %c0,%c0,.LctlS1-.LbaseS1(%r13)
71 st %r0,.LctlS1-.LbaseS1(%r13)
72 lhi %r2,2 # return code for timeout
73.LloopS1:
74 lpsw .LwaitpswS1-.LbaseS1(%r13) # wait until interrupt
75.LwaitS1:
76 lh %r7,LC_EXT_INT_CODE
77 chi %r7,EXT_IRQ_CLK_COMP # timeout?
78 je .LtimeoutS1
79 chi %r7,EXT_IRQ_SERVICE_SIG # service int?
80 jne .LloopS1
81 sr %r2,%r2
82 l %r3,LC_EXT_INT_PARAM
83.LtimeoutS1:
84 lctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # restore interrupt setting
85 # restore old handler
86 mvc 0(16,%r8),.LoldpswS1-.LbaseS1(%r13)
87 lm %r6,%r15,120(%r15) # restore registers
88 br %r14 # return to caller
89
90 .align 8
91.LoldpswS1:
92 .long 0, 0, 0, 0 # old ext int PSW
93.LextpswS1:
94 .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int
95#ifdef CONFIG_64BIT
96.LextpswS1_64:
97 .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit
98#endif
99.LwaitpswS1:
100 .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int
101.LtimeS1:
102 .quad 0 # current time
103.LctlS1:
104 .long 0 # CT0 contents
105
106#
107# Subroutine to synchronously issue a service call.
108#
109# Parameters:
110# R2 = command word
111# R3 = sccb address
112#
113# Returns:
114# R2 = 0 on success, 1 on failure
115# R3 = sccb response code if R2 = 0
116#
117
118_sclp_servc:
119 stm %r6,%r15,24(%r15) # save registers
120 ahi %r15,-96 # create stack frame
121 lr %r6,%r2 # save command word
122 lr %r7,%r3 # save sccb address
123.LretryS2:
124 lhi %r2,1 # error return code
125 .insn rre,0xb2200000,%r6,%r7 # servc
126 brc 1,.LendS2 # exit if not operational
127 brc 8,.LnotbusyS2 # go on if not busy
128 sr %r2,%r2 # wait until no longer busy
129 bras %r14,_sclp_wait_int
130 j .LretryS2 # retry
131.LnotbusyS2:
132 sr %r2,%r2 # wait until result
133 bras %r14,_sclp_wait_int
134 sr %r2,%r2
135 lh %r3,6(%r7)
136.LendS2:
137 lm %r6,%r15,120(%r15) # restore registers
138 br %r14
139
140#
141# Subroutine to set up the SCLP interface.
142#
143# Parameters:
144# R2 = 0 to activate, non-zero to deactivate
145#
146# Returns:
147# R2 = 0 on success, non-zero on failure
148#
149
150_sclp_setup:
151 stm %r6,%r15,24(%r15) # save registers
152 ahi %r15,-96 # create stack frame
153 basr %r13,0 # get base register
154.LbaseS3:
155 l %r6,.LsccbS0-.LbaseS3(%r13) # prepare init mask sccb
156 mvc 0(.LinitendS3-.LinitsccbS3,%r6),.LinitsccbS3-.LbaseS3(%r13)
157 ltr %r2,%r2 # initialization?
158 jz .LdoinitS3 # go ahead
159 # clear masks
160 xc .LinitmaskS3-.LinitsccbS3(8,%r6),.LinitmaskS3-.LinitsccbS3(%r6)
161.LdoinitS3:
162 l %r2,.LwritemaskS3-.LbaseS3(%r13)# get command word
163 lr %r3,%r6 # get sccb address
164 bras %r14,_sclp_servc # issue service call
165 ltr %r2,%r2 # servc successful?
166 jnz .LerrorS3
167 chi %r3,0x20 # write mask successful?
168 jne .LerrorS3
169 # check masks
170 la %r2,.LinitmaskS3-.LinitsccbS3(%r6)
171 l %r1,0(%r2) # receive mask ok?
172 n %r1,12(%r2)
173 cl %r1,0(%r2)
174 jne .LerrorS3
175 l %r1,4(%r2) # send mask ok?
176 n %r1,8(%r2)
177 cl %r1,4(%r2)
178 sr %r2,%r2
179 je .LendS3
180.LerrorS3:
181 lhi %r2,1 # error return code
182.LendS3:
183 lm %r6,%r15,120(%r15) # restore registers
184 br %r14
185.LwritemaskS3:
186 .long 0x00780005 # SCLP command for write mask
187.LinitsccbS3:
188 .word .LinitendS3-.LinitsccbS3
189 .byte 0,0,0,0
190 .word 0
191 .word 0
192 .word 4
193.LinitmaskS3:
194 .long 0x80000000
195 .long 0x40000000
196 .long 0
197 .long 0
198.LinitendS3:
199
200#
201# Subroutine which prints a given text to the SCLP console.
202#
203# Parameters:
204# R2 = address of nil-terminated ASCII text
205#
206# Returns:
207# R2 = 0 on success, 1 on failure
208#
209
210_sclp_print:
211 stm %r6,%r15,24(%r15) # save registers
212 ahi %r15,-96 # create stack frame
213 basr %r13,0 # get base register
214.LbaseS4:
215 l %r8,.LsccbS0-.LbaseS4(%r13) # prepare write data sccb
216 mvc 0(.LmtoS4-.LwritesccbS4,%r8),.LwritesccbS4-.LbaseS4(%r13)
217 la %r7,.LmtoS4-.LwritesccbS4(%r8) # current mto addr
218 sr %r0,%r0
219 l %r10,.Lascebc-.LbaseS4(%r13) # address of translation table
220.LinitmtoS4:
221 # initialize mto
222 mvc 0(.LmtoendS4-.LmtoS4,%r7),.LmtoS4-.LbaseS4(%r13)
223 lhi %r6,.LmtoendS4-.LmtoS4 # current mto length
224.LloopS4:
225 ic %r0,0(%r2) # get character
226 ahi %r2,1
227 ltr %r0,%r0 # end of string?
228 jz .LfinalizemtoS4
229 chi %r0,0x0a # end of line (NL)?
230 jz .LfinalizemtoS4
231 stc %r0,0(%r6,%r7) # copy to mto
232 la %r11,0(%r6,%r7)
233 tr 0(1,%r11),0(%r10) # translate to EBCDIC
234 ahi %r6,1
235 j .LloopS4
236.LfinalizemtoS4:
237 sth %r6,0(%r7) # update mto length
238 lh %r9,.LmdbS4-.LwritesccbS4(%r8) # update mdb length
239 ar %r9,%r6
240 sth %r9,.LmdbS4-.LwritesccbS4(%r8)
241 lh %r9,.LevbufS4-.LwritesccbS4(%r8)# update evbuf length
242 ar %r9,%r6
243 sth %r9,.LevbufS4-.LwritesccbS4(%r8)
244 lh %r9,0(%r8) # update sccb length
245 ar %r9,%r6
246 sth %r9,0(%r8)
247 ar %r7,%r6 # update current mto address
248 ltr %r0,%r0 # more characters?
249 jnz .LinitmtoS4
250 l %r2,.LwritedataS4-.LbaseS4(%r13)# write data
251 lr %r3,%r8
252 bras %r14,_sclp_servc
253 ltr %r2,%r2 # servc successful?
254 jnz .LendS4
255 chi %r3,0x20 # write data successful?
256 je .LendS4
257 lhi %r2,1 # error return code
258.LendS4:
259 lm %r6,%r15,120(%r15) # restore registers
260 br %r14
261
262#
263# Function which prints a given text to the SCLP console.
264#
265# Parameters:
266# R2 = address of nil-terminated ASCII text
267#
268# Returns:
269# R2 = 0 on success, 1 on failure
270#
271
272ENTRY(_sclp_print_early)
273 stm %r6,%r15,24(%r15) # save registers
274 ahi %r15,-96 # create stack frame
275#ifdef CONFIG_64BIT
276 tm LC_AR_MODE_ID,1
277 jno .Lesa2
278 ahi %r15,-80
279 stmh %r6,%r15,96(%r15) # store upper register halves
280.Lesa2:
281#endif
282 lr %r10,%r2 # save string pointer
283 lhi %r2,0
284 bras %r14,_sclp_setup # enable console
285 ltr %r2,%r2
286 jnz .LendS5
287 lr %r2,%r10
288 bras %r14,_sclp_print # print string
289 ltr %r2,%r2
290 jnz .LendS5
291 lhi %r2,1
292 bras %r14,_sclp_setup # disable console
293.LendS5:
294#ifdef CONFIG_64BIT
295 tm LC_AR_MODE_ID,1
296 jno .Lesa3
297 lmh %r6,%r15,96(%r15) # store upper register halves
298 ahi %r15,80
299.Lesa3:
300#endif
301 lm %r6,%r15,120(%r15) # restore registers
302 br %r14
303
304.LwritedataS4:
305 .long 0x00760005 # SCLP command for write data
306.LwritesccbS4:
307 # sccb
308 .word .LmtoS4-.LwritesccbS4
309 .byte 0
310 .byte 0,0,0
311 .word 0
312
313 # evbuf
314.LevbufS4:
315 .word .LmtoS4-.LevbufS4
316 .byte 0x02
317 .byte 0
318 .word 0
319
320.LmdbS4:
321 # mdb
322 .word .LmtoS4-.LmdbS4
323 .word 1
324 .long 0xd4c4c240
325 .long 1
326
327 # go
328.LgoS4:
329 .word .LmtoS4-.LgoS4
330 .word 1
331 .long 0
332 .byte 0,0,0,0,0,0,0,0
333 .byte 0,0,0
334 .byte 0
335 .byte 0,0,0,0,0,0,0
336 .byte 0
337 .word 0
338 .byte 0,0,0,0,0,0,0,0,0,0
339 .byte 0,0,0,0,0,0,0,0
340 .byte 0,0,0,0,0,0,0,0
341
342.LmtoS4:
343 .word .LmtoendS4-.LmtoS4
344 .word 4
345 .word 0x1000
346 .byte 0
347 .byte 0,0,0
348.LmtoendS4:
349
350 # Global constants
351.LsccbS0:
352 .long _sclp_work_area
353.Lascebc:
354 .long _ascebc
355
356.section .data,"aw",@progbits
357 .balign 4096
358_sclp_work_area:
359 .fill 4096
360.previous