1 /* UART model. 2 3 Copyright (C) 1996-2023 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 /* This must come before any other includes. */ 22 #include "defs.h" 23 24 #include "sim-main.h" 25 #include "hw-main.h" 26 27 #include "dv-sockser.h" 28 #include "dv-m32r_uart.h" 29 30 struct m32r_uart 31 { 32 }; 33 34 static unsigned 35 m32r_uart_io_write_buffer (struct hw *me, const void *source, 36 int space, address_word addr, unsigned nr_bytes) 37 { 38 SIM_DESC sd = hw_system (me); 39 struct m32r_uart *uart = hw_data (me); 40 int status = dv_sockser_status (sd); 41 42 switch (addr) 43 { 44 case UART_OUTCHAR_ADDR: 45 if (status & DV_SOCKSER_DISCONNECTED) 46 { 47 sim_io_write_stdout (sd, source, nr_bytes); 48 sim_io_flush_stdout (sd); 49 } 50 else 51 { 52 /* Normalize errors to a value of 0. */ 53 int ret = dv_sockser_write_buffer (sd, source, nr_bytes); 54 if (ret < 0) 55 nr_bytes = 0; 56 } 57 break; 58 } 59 60 return nr_bytes; 61 } 62 63 static unsigned 64 m32r_uart_io_read_buffer (struct hw *me, void *dest, 65 int space, address_word addr, unsigned nr_bytes) 66 { 67 SIM_DESC sd = hw_system (me); 68 struct m32r_uart *uart = hw_data (me); 69 int status = dv_sockser_status (sd); 70 71 switch (addr) 72 { 73 case UART_INCHAR_ADDR: 74 if (status & DV_SOCKSER_DISCONNECTED) 75 { 76 int ret = sim_io_poll_read (sd, 0/*STDIN*/, dest, 1); 77 return (ret < 0) ? 0 : 1; 78 } 79 else 80 { 81 char *buffer = dest; 82 buffer[0] = dv_sockser_read (sd); 83 return 1; 84 } 85 case UART_STATUS_ADDR: 86 { 87 unsigned char *p = dest; 88 p[0] = 0; 89 p[1] = (((status & DV_SOCKSER_INPUT_EMPTY) 90 #ifdef UART_INPUT_READY0 91 ? UART_INPUT_READY : 0) 92 #else 93 ? 0 : UART_INPUT_READY) 94 #endif 95 + ((status & DV_SOCKSER_OUTPUT_EMPTY) ? UART_OUTPUT_READY : 0)); 96 return 2; 97 } 98 } 99 100 return nr_bytes; 101 } 102 103 static void 104 attach_m32r_uart_regs (struct hw *me, struct m32r_uart *uart) 105 { 106 address_word attach_address; 107 int attach_space; 108 unsigned attach_size; 109 reg_property_spec reg; 110 111 if (hw_find_property (me, "reg") == NULL) 112 hw_abort (me, "Missing \"reg\" property"); 113 114 if (!hw_find_reg_array_property (me, "reg", 0, ®)) 115 hw_abort (me, "\"reg\" property must contain three addr/size entries"); 116 117 hw_unit_address_to_attach_address (hw_parent (me), 118 ®.address, 119 &attach_space, &attach_address, me); 120 hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me); 121 122 hw_attach_address (hw_parent (me), 123 0, attach_space, attach_address, attach_size, me); 124 } 125 126 static void 127 m32r_uart_finish (struct hw *me) 128 { 129 struct m32r_uart *uart; 130 131 uart = HW_ZALLOC (me, struct m32r_uart); 132 133 set_hw_data (me, uart); 134 set_hw_io_read_buffer (me, m32r_uart_io_read_buffer); 135 set_hw_io_write_buffer (me, m32r_uart_io_write_buffer); 136 137 attach_m32r_uart_regs (me, uart); 138 } 139 140 const struct hw_descriptor dv_m32r_uart_descriptor[] = 141 { 142 {"m32r_uart", m32r_uart_finish,}, 143 {NULL, NULL}, 144 }; 145