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