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 <libcflat.h> 12 #include <string.h> 13 #include <asm/page.h> 14 #include "sclp.h" 15 16 char _sccb[PAGE_SIZE] __attribute__((__aligned__(4096))); 17 18 /* Perform service call. Return 0 on success, non-zero otherwise. */ 19 int sclp_service_call(unsigned int command, void *sccb) 20 { 21 int cc; 22 23 asm volatile( 24 " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */ 25 " ipm %0\n" 26 " srl %0,28" 27 : "=&d" (cc) : "d" (command), "a" (__pa(sccb)) 28 : "cc", "memory"); 29 if (cc == 3) 30 return -1; 31 if (cc == 2) 32 return -1; 33 return 0; 34 } 35 36 static void sclp_set_write_mask(void) 37 { 38 WriteEventMask *sccb = (void *)_sccb; 39 40 sccb->h.length = sizeof(WriteEventMask); 41 sccb->mask_length = sizeof(unsigned int); 42 sccb->receive_mask = SCLP_EVENT_MASK_MSG_ASCII; 43 sccb->cp_receive_mask = SCLP_EVENT_MASK_MSG_ASCII; 44 sccb->send_mask = SCLP_EVENT_MASK_MSG_ASCII; 45 sccb->cp_send_mask = SCLP_EVENT_MASK_MSG_ASCII; 46 47 sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK, sccb); 48 } 49 50 void sclp_console_setup(void) 51 { 52 sclp_set_write_mask(); 53 } 54 55 void sclp_print(const char *str) 56 { 57 int len = strlen(str); 58 WriteEventData *sccb = (void *)_sccb; 59 60 sccb->h.length = sizeof(WriteEventData) + len; 61 sccb->h.function_code = SCLP_FC_NORMAL_WRITE; 62 sccb->ebh.length = sizeof(EventBufferHeader) + len; 63 sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA; 64 sccb->ebh.flags = 0; 65 memcpy(sccb->data, str, len); 66 67 sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb); 68 } 69