1 /* UART model. 2 3 Copyright (C) 1996-2024 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 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 int status = dv_sockser_status (sd); 68 69 switch (addr) 70 { 71 case UART_INCHAR_ADDR: 72 if (status & DV_SOCKSER_DISCONNECTED) 73 { 74 int ret = sim_io_poll_read (sd, 0/*STDIN*/, dest, 1); 75 return (ret < 0) ? 0 : 1; 76 } 77 else 78 { 79 char *buffer = dest; 80 buffer[0] = dv_sockser_read (sd); 81 return 1; 82 } 83 case UART_STATUS_ADDR: 84 { 85 unsigned char *p = dest; 86 p[0] = 0; 87 p[1] = (((status & DV_SOCKSER_INPUT_EMPTY) 88 #ifdef UART_INPUT_READY0 89 ? UART_INPUT_READY : 0) 90 #else 91 ? 0 : UART_INPUT_READY) 92 #endif 93 + ((status & DV_SOCKSER_OUTPUT_EMPTY) ? UART_OUTPUT_READY : 0)); 94 return 2; 95 } 96 } 97 98 return nr_bytes; 99 } 100 101 static void 102 attach_m32r_uart_regs (struct hw *me, struct m32r_uart *uart) 103 { 104 address_word attach_address; 105 int attach_space; 106 unsigned attach_size; 107 reg_property_spec reg; 108 109 if (hw_find_property (me, "reg") == NULL) 110 hw_abort (me, "Missing \"reg\" property"); 111 112 if (!hw_find_reg_array_property (me, "reg", 0, ®)) 113 hw_abort (me, "\"reg\" property must contain three addr/size entries"); 114 115 hw_unit_address_to_attach_address (hw_parent (me), 116 ®.address, 117 &attach_space, &attach_address, me); 118 hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me); 119 120 hw_attach_address (hw_parent (me), 121 0, attach_space, attach_address, attach_size, me); 122 } 123 124 static void 125 m32r_uart_finish (struct hw *me) 126 { 127 struct m32r_uart *uart; 128 129 uart = HW_ZALLOC (me, struct m32r_uart); 130 131 set_hw_data (me, uart); 132 set_hw_io_read_buffer (me, m32r_uart_io_read_buffer); 133 set_hw_io_write_buffer (me, m32r_uart_io_write_buffer); 134 135 attach_m32r_uart_regs (me, uart); 136 } 137 138 const struct hw_descriptor dv_m32r_uart_descriptor[] = 139 { 140 {"m32r_uart", m32r_uart_finish,}, 141 {NULL, NULL}, 142 }; 143