1/** 2 * \file 3 * \brief "Serial" driver on host side 4 */ 5 6/* 7 * Copyright (c) 2014 ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <stdio.h> 16#include <string.h> 17#include <barrelfish/barrelfish.h> 18 19 20 21#include "xeon_phi_internal.h" 22 23#define XEON_PHI_BUFFER_LENGTH 0x400 24#define XEON_PHI_POLL_GIVEUP 0x100 25 26 27#define ANSI_COLOR_RED "\x1b[31m" 28#define ANSI_COLOR_GREEN "\x1b[32m" 29#define ANSI_COLOR_YELLOW "\x1b[33m" 30#define ANSI_COLOR_BLUE "\x1b[34m" 31#define ANSI_COLOR_MAGENTA "\x1b[35m" 32#define ANSI_COLOR_CYAN "\x1b[36m" 33#define ANSI_COLOR_RESET "\x1b[0m" 34 35static inline void xprintf(uint8_t xid, 36 char *fmt) 37{ 38 switch (xid) { 39 case 0: 40 printf(ANSI_COLOR_YELLOW">> XEON_PHI.%u"ANSI_COLOR_RESET": %s\n", xid, fmt); 41 break; 42 case 1: 43 printf(ANSI_COLOR_MAGENTA">> XEON_PHI.%u"ANSI_COLOR_RESET": %s\n", xid, fmt); 44 break; 45 default: 46 printf("\x1b[32m>> XEON_PHI \033[31m%u\033[0m: %s\n", xid, fmt); 47 break; 48 } 49} 50 51uint32_t xeon_phi_serial_handle_recv(struct xeon_phi *phi) 52{ 53 xeon_phi_serial_ctrl_t sctrl = xeon_phi_serial_reset; 54 xeon_phi_serial_data_t sdata = xeon_phi_serial_reset; 55 56 sctrl = xeon_phi_serial_ctrl_rd(&phi->serial_base); 57 58 if (!sctrl) { 59 return 0; 60 } 61 62 uint32_t i = 0; 63 sdata = xeon_phi_serial_data_rd(&phi->serial_base); 64 uint8_t has_data = 0; 65 uint8_t value = 0; 66 while (i < 4) { 67 switch (i) { 68 case 0: 69 has_data = xeon_phi_serial_ctrl_value0_extract(sctrl); 70 value = xeon_phi_serial_data_value0_extract(sdata); 71 break; 72 case 1: 73 has_data = xeon_phi_serial_ctrl_value1_extract(sctrl); 74 value = xeon_phi_serial_data_value1_extract(sdata); 75 break; 76 case 2: 77 has_data = xeon_phi_serial_ctrl_value2_extract(sctrl); 78 value = xeon_phi_serial_data_value2_extract(sdata); 79 break; 80 case 3: 81 has_data = xeon_phi_serial_ctrl_value3_extract(sctrl); 82 value = xeon_phi_serial_data_value3_extract(sdata); 83 break; 84 } 85 86 if ((has_data & 0x80) || !has_data) { 87 i++; 88 continue; 89 } 90 if (has_data != xeon_phi_serial_data) { 91 debug_printf("[xeon phi %d] : ERROR invalid ctrl value.%x\n", 92 phi->id, 93 has_data); 94 } 95 /* always issue a new line */ 96 if (value == '\n') { 97 phi->serial_buffer[phi->serial_buffer_idx] = '\0'; 98 xprintf(phi->id, phi->serial_buffer); 99 phi->serial_buffer_idx = 0; 100 /* there was a "flush" so flush buffer to log */ 101 } else if (value == 0x4) { 102 phi->serial_buffer[phi->serial_buffer_idx] = '\0'; 103 xprintf(phi->id, phi->serial_buffer); 104 phi->serial_buffer_idx = 0; 105 /* buffer is full, flush buffer */ 106 } else if (phi->serial_buffer_idx == XEON_PHI_BUFFER_LENGTH) { 107 phi->serial_buffer[phi->serial_buffer_idx] = '\0'; 108 xprintf(phi->id, phi->serial_buffer); 109 phi->serial_buffer[0] = value; 110 phi->serial_buffer_idx = 1; 111 /* just store the char */ 112 } else { 113 phi->serial_buffer[phi->serial_buffer_idx] = value; 114 phi->serial_buffer_idx++; 115 } 116 i++; 117 } 118 /* acknowledge the data receive */ 119 xeon_phi_serial_ctrl_rawwr(&phi->serial_base, xeon_phi_serial_reset); 120 121 return 1; 122} 123 124static int xeon_phi_recv_handler(void *arg) 125{ 126 uint32_t nodata; 127 128 struct xeon_phi *phi = arg; 129 130 debug_printf("[xeon phi %d] : receive handler started.\n", phi->id); 131 132 nodata = XEON_PHI_POLL_GIVEUP; 133 134 135 136 while (1) { 137 if (!xeon_phi_serial_handle_recv(arg)) { 138 if (--nodata) { 139 continue; 140 } 141 142 // reset counter 143 nodata = XEON_PHI_POLL_GIVEUP; 144 145 thread_yield(); 146 147 continue; 148 } 149 } 150 151 debug_printf("[xeon phi %d] : thread terminated.\n ", phi->id); 152 153 return 0; 154} 155 156/** 157 * \brief initializes a new thread for receiving the serial out of the card 158 * 159 * The sbox memory region has already been mapped 160 */ 161errval_t xeon_phi_serial_start_recv_thread(struct xeon_phi *phi) 162{ 163 if (phi->serial_base.base == NULL) { 164 xeon_phi_serial_init(phi); 165 } 166 167 xeon_phi_recv_handler(phi); 168 //thread_create(xeon_phi_recv_handler, xarg); 169 170 return SYS_ERR_OK; 171} 172 173/** 174 * \brief initializes the serial receiver 175 * 176 * \param phi pointer to the card information 177 */ 178errval_t xeon_phi_serial_init(struct xeon_phi *phi) 179{ 180 181 xeon_phi_serial_initialize(&phi->serial_base, XEON_PHI_MMIO_TO_SBOX(phi)); 182 183 xeon_phi_serial_ctrl_rawwr(&phi->serial_base, xeon_phi_serial_reset); 184 185 phi->serial_buffer_idx = 0; 186 memset(phi->serial_buffer, 0, sizeof(phi->serial_buffer)); 187 188 return SYS_ERR_OK; 189} 190