1 /* UART model. 2 3 Copyright (C) 1996-2019 Free Software Foundation, Inc. 4 Contributed by Cygnus Solutions and Mike Frysinger. 5 6 This file is part of simulators. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 23 #include "sim-main.h" 24 #include "hw-main.h" 25 26 #include "dv-sockser.h" 27 #include "dv-m32r_uart.h" 28 29 struct m32r_uart 30 { 31 }; 32 33 static unsigned 34 m32r_uart_io_write_buffer (struct hw *me, const void *source, 35 int space, address_word addr, unsigned nr_bytes) 36 { 37 SIM_DESC sd = hw_system (me); 38 struct m32r_uart *uart = hw_data (me); 39 int status = dv_sockser_status (sd); 40 41 switch (addr) 42 { 43 case UART_OUTCHAR_ADDR: 44 if (status & DV_SOCKSER_DISCONNECTED) 45 { 46 sim_io_write_stdout (sd, source, nr_bytes); 47 sim_io_flush_stdout (sd); 48 } 49 else 50 { 51 /* Normalize errors to a value of 0. */ 52 int ret = dv_sockser_write_buffer (sd, source, nr_bytes); 53 if (ret < 0) 54 nr_bytes = 0; 55 } 56 break; 57 } 58 59 return nr_bytes; 60 } 61 62 static unsigned 63 m32r_uart_io_read_buffer (struct hw *me, void *dest, 64 int space, address_word addr, unsigned nr_bytes) 65 { 66 SIM_DESC sd = hw_system (me); 67 struct m32r_uart *uart = hw_data (me); 68 int status = dv_sockser_status (sd); 69 70 switch (addr) 71 { 72 case UART_INCHAR_ADDR: 73 if (status & DV_SOCKSER_DISCONNECTED) 74 { 75 int ret = sim_io_poll_read (sd, 0/*STDIN*/, dest, 1); 76 return (ret < 0) ? 0 : 1; 77 } 78 else 79 { 80 char *buffer = dest; 81 buffer[0] = dv_sockser_read (sd); 82 return 1; 83 } 84 case UART_STATUS_ADDR: 85 { 86 unsigned char *p = dest; 87 p[0] = 0; 88 p[1] = (((status & DV_SOCKSER_INPUT_EMPTY) 89 #ifdef UART_INPUT_READY0 90 ? UART_INPUT_READY : 0) 91 #else 92 ? 0 : UART_INPUT_READY) 93 #endif 94 + ((status & DV_SOCKSER_OUTPUT_EMPTY) ? UART_OUTPUT_READY : 0)); 95 return 2; 96 } 97 } 98 99 return nr_bytes; 100 } 101 102 static void 103 attach_m32r_uart_regs (struct hw *me, struct m32r_uart *uart) 104 { 105 address_word attach_address; 106 int attach_space; 107 unsigned attach_size; 108 reg_property_spec reg; 109 110 if (hw_find_property (me, "reg") == NULL) 111 hw_abort (me, "Missing \"reg\" property"); 112 113 if (!hw_find_reg_array_property (me, "reg", 0, ®)) 114 hw_abort (me, "\"reg\" property must contain three addr/size entries"); 115 116 hw_unit_address_to_attach_address (hw_parent (me), 117 ®.address, 118 &attach_space, &attach_address, me); 119 hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me); 120 121 hw_attach_address (hw_parent (me), 122 0, attach_space, attach_address, attach_size, me); 123 } 124 125 static void 126 m32r_uart_finish (struct hw *me) 127 { 128 struct m32r_uart *uart; 129 130 uart = HW_ZALLOC (me, struct m32r_uart); 131 132 set_hw_data (me, uart); 133 set_hw_io_read_buffer (me, m32r_uart_io_read_buffer); 134 set_hw_io_write_buffer (me, m32r_uart_io_write_buffer); 135 136 attach_m32r_uart_regs (me, uart); 137 } 138 139 const struct hw_descriptor dv_m32r_uart_descriptor[] = 140 { 141 {"m32r_uart", m32r_uart_finish,}, 142 {NULL, NULL}, 143 }; 144