root / pc-bios / s390-ccw / sclp-ascii.c @ 0369b2eb
History | View | Annotate | Download (2 kB)
1 |
/*
|
---|---|
2 |
* SCLP ASCII access driver
|
3 |
*
|
4 |
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
|
5 |
*
|
6 |
* This work is licensed under the terms of the GNU GPL, version 2 or (at
|
7 |
* your option) any later version. See the COPYING file in the top-level
|
8 |
* directory.
|
9 |
*/
|
10 |
|
11 |
#include "s390-ccw.h" |
12 |
#include "sclp.h" |
13 |
|
14 |
static char _sccb[PAGE_SIZE] __attribute__((__aligned__(4096))); |
15 |
|
16 |
/* Perform service call. Return 0 on success, non-zero otherwise. */
|
17 |
static int sclp_service_call(unsigned int command, void *sccb) |
18 |
{ |
19 |
int cc;
|
20 |
|
21 |
asm volatile( |
22 |
" .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */ |
23 |
" ipm %0\n"
|
24 |
" srl %0,28"
|
25 |
: "=&d" (cc) : "d" (command), "a" (__pa(sccb)) |
26 |
: "cc", "memory"); |
27 |
if (cc == 3) |
28 |
return -EIO;
|
29 |
if (cc == 2) |
30 |
return -EBUSY;
|
31 |
return 0; |
32 |
} |
33 |
|
34 |
static void sclp_set_write_mask(void) |
35 |
{ |
36 |
WriteEventMask *sccb = (void*)_sccb;
|
37 |
|
38 |
sccb->h.length = sizeof(WriteEventMask);
|
39 |
sccb->mask_length = sizeof(unsigned int); |
40 |
sccb->receive_mask = SCLP_EVENT_MASK_MSG_ASCII; |
41 |
sccb->cp_receive_mask = SCLP_EVENT_MASK_MSG_ASCII; |
42 |
sccb->send_mask = SCLP_EVENT_MASK_MSG_ASCII; |
43 |
sccb->cp_send_mask = SCLP_EVENT_MASK_MSG_ASCII; |
44 |
|
45 |
sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK, sccb); |
46 |
} |
47 |
|
48 |
void sclp_setup(void) |
49 |
{ |
50 |
sclp_set_write_mask(); |
51 |
} |
52 |
|
53 |
static int _strlen(const char *str) |
54 |
{ |
55 |
int i;
|
56 |
for (i = 0; *str; i++) |
57 |
str++; |
58 |
return i;
|
59 |
} |
60 |
|
61 |
static void _memcpy(char *dest, const char *src, int len) |
62 |
{ |
63 |
int i;
|
64 |
for (i = 0; i < len; i++) |
65 |
dest[i] = src[i]; |
66 |
} |
67 |
|
68 |
void sclp_print(const char *str) |
69 |
{ |
70 |
int len = _strlen(str);
|
71 |
WriteEventData *sccb = (void*)_sccb;
|
72 |
|
73 |
sccb->h.length = sizeof(WriteEventData) + len;
|
74 |
sccb->h.function_code = SCLP_FC_NORMAL_WRITE; |
75 |
sccb->ebh.length = sizeof(EventBufferHeader) + len;
|
76 |
sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA; |
77 |
sccb->ebh.flags = 0;
|
78 |
_memcpy(sccb->data, str, len); |
79 |
|
80 |
sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb); |
81 |
} |