pc-bios/s390-ccw: zero out bss section
[qemu/ar7.git] / pc-bios / s390-ccw / sclp.c
blob90d1bc314788092a0edf9de59ca6db6a6ec85b00
1 /*
2 * SCLP ASCII access driver
4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
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 */
11 #include "libc.h"
12 #include "s390-ccw.h"
13 #include "sclp.h"
15 long write(int fd, const void *str, size_t len);
17 static char _sccb[PAGE_SIZE] __attribute__((__aligned__(4096)));
19 const unsigned char ebc2asc[256] =
20 /* 0123456789abcdef0123456789abcdef */
21 "................................" /* 1F */
22 "................................" /* 3F */
23 " ...........<(+|&.........!$*);." /* 5F first.chr.here.is.real.space */
24 "-/.........,%_>?.........`:#@'=\""/* 7F */
25 ".abcdefghi.......jklmnopqr......" /* 9F */
26 "..stuvwxyz......................" /* BF */
27 ".ABCDEFGHI.......JKLMNOPQR......" /* DF */
28 "..STUVWXYZ......0123456789......";/* FF */
30 /* Perform service call. Return 0 on success, non-zero otherwise. */
31 static int sclp_service_call(unsigned int command, void *sccb)
33 int cc;
35 asm volatile(
36 " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
37 " ipm %0\n"
38 " srl %0,28"
39 : "=&d" (cc) : "d" (command), "a" (__pa(sccb))
40 : "cc", "memory");
41 consume_sclp_int();
42 if (cc == 3)
43 return -EIO;
44 if (cc == 2)
45 return -EBUSY;
46 return 0;
49 static void sclp_set_write_mask(void)
51 WriteEventMask *sccb = (void *)_sccb;
53 sccb->h.length = sizeof(WriteEventMask);
54 sccb->mask_length = sizeof(unsigned int);
55 sccb->receive_mask = SCLP_EVENT_MASK_MSG_ASCII;
56 sccb->cp_receive_mask = SCLP_EVENT_MASK_MSG_ASCII;
57 sccb->send_mask = SCLP_EVENT_MASK_MSG_ASCII;
58 sccb->cp_send_mask = SCLP_EVENT_MASK_MSG_ASCII;
60 sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK, sccb);
63 void sclp_setup(void)
65 sclp_set_write_mask();
68 static int _strlen(const char *str)
70 int i;
71 for (i = 0; *str; i++)
72 str++;
73 return i;
76 long write(int fd, const void *str, size_t len)
78 WriteEventData *sccb = (void *)_sccb;
79 const char *p = str;
80 size_t data_len = 0;
81 size_t i;
83 if (fd != 1 && fd != 2) {
84 return -EIO;
87 for (i = 0; i < len; i++) {
88 if ((data_len + 1) >= SCCB_DATA_LEN) {
89 /* We would overflow the sccb buffer, abort early */
90 len = i;
91 break;
94 if (*p == '\n') {
95 /* Terminal emulators might need \r\n, so generate it */
96 sccb->data[data_len++] = '\r';
99 sccb->data[data_len++] = *p;
100 p++;
103 sccb->h.length = sizeof(WriteEventData) + data_len;
104 sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
105 sccb->ebh.length = sizeof(EventBufferHeader) + data_len;
106 sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
107 sccb->ebh.flags = 0;
109 sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb);
111 return len;
114 void sclp_print(const char *str)
116 write(1, str, _strlen(str));
119 void sclp_get_loadparm_ascii(char *loadparm)
122 ReadInfo *sccb = (void *)_sccb;
124 memset((char *)_sccb, 0, sizeof(ReadInfo));
125 sccb->h.length = sizeof(ReadInfo);
126 if (!sclp_service_call(SCLP_CMDW_READ_SCP_INFO, sccb)) {
127 ebcdic_to_ascii((char *) sccb->loadparm, loadparm, 8);