/* This file is part of the program GDB, the GNU debugger.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998-2020 Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sim-main.h"
#include "hw-main.h"
#include "dv-sockser.h"
-
+#include "sim-assert.h"
/* DEVICE
static char tx3904sio_fifo_pop(struct hw*, struct tx3904sio_fifo*);
static void tx3904sio_fifo_push(struct hw*, struct tx3904sio_fifo*, char);
static void tx3904sio_fifo_reset(struct hw*, struct tx3904sio_fifo*);
-
+static void tx3904sio_poll(struct hw*, void* data);
/* register numbers; each is one word long */
unsigned_4 sdisr;
#define SDISR_WR_MASK 0x00070000U
#define SDISR_SET_BYTE(c,o,b) ((c)->sdisr = SDISR_WR_MASK & (((c)->sdisr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+#define SDISR_CLEAR_FLAG_BYTE(c,o,b) ((c)->sdisr = SDISR_WR_MASK & (((c)->sdisr & ~LSMASK32((o)*8+7,(o)*8)) & ((b)<< (o)*8)))
#define SDISR_GET_TDIS(c) ((c)->sdisr & 0x00020000)
#define SDISR_SET_TDIS(c) ((c)->sdisr |= 0x00020000)
#define SDISR_GET_RDIS(c) ((c)->sdisr & 0x00010000)
unsigned_4 sbgr;
#define SBGR_WR_MASK 0x03ff0000U
#define SBGR_SET_BYTE(c,o,b) ((c)->sbgr = SBGR_WR_MASK & (((c)->sbgr & ~LSMASK32((o)*8+7,(o)*8)) | ((b)<< (o)*8)))
+
+ /* Periodic I/O polling */
+ struct hw_event* poll_event;
};
= controller->sbgr = 0;
controller->slcr = 0x40000000; /* set TWUB */
controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */
+ controller->poll_event = NULL;
}
= controller->sbgr = 0;
controller->slcr = 0x40000000; /* set TWUB */
controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */
+ /* Don't interfere with I/O poller. */
break;
}
{
address_word address = base + byte;
int reg_number = (address - controller->base_address) / 4;
- int reg_offset = 3 - (address - controller->base_address) % 4;
+ int reg_offset = (address - controller->base_address) % 4;
unsigned_4 register_value; /* in target byte order */
/* fill in entire register_value word */
case TFIFO_REG: register_value = 0; break;
case SFIFO_REG:
/* consume rx fifo for MS byte */
- if(reg_offset == 3 && tx3904sio_fifo_nonempty(me, & controller->rx_fifo))
+ if(reg_offset == 0 && tx3904sio_fifo_nonempty(me, & controller->rx_fifo))
register_value = (tx3904sio_fifo_pop(me, & controller->rx_fifo) << 24);
else
register_value = 0;
}
/* write requested byte out */
+ register_value = H2T_4(register_value);
+ /* HW_TRACE ((me, "byte %d %02x", reg_offset, ((char*)& register_value)[reg_offset])); */
memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
}
int reg_number = (address - controller->base_address) / 4;
int reg_offset = 3 - (address - controller->base_address) % 4;
- HW_TRACE ((me, "byte %d %02x", reg_offset, write_byte));
+ /* HW_TRACE ((me, "byte %d %02x", reg_offset, write_byte)); */
/* fill in entire register_value word */
switch (reg_number)
last_int = controller->sdisr & controller->sdicr;
/* HW_TRACE ((me, "sdisr - sdisr %08x sdicr %08x",
controller->sdisr, controller->sdicr)); */
- SDISR_SET_BYTE(controller, reg_offset, write_byte);
+ SDISR_CLEAR_FLAG_BYTE(controller, reg_offset, write_byte);
/* HW_TRACE ((me, "sdisr + sdisr %08x sdicr %08x",
controller->sdisr, controller->sdicr)); */
next_int = controller->sdisr & controller->sdicr;
{
cc = tx3904sio_fifo_pop(me, & controller->tx_fifo);
sim_io_write_stdout(hw_system(me), & cc, 1);
+ sim_io_flush_stdout(hw_system(me));
HW_TRACE ((me, "stdio output: %02x", cc));
}
hw_port_event(me, INT_PORT, 1);
if(last_int & ~next_int) /* any bits cleared? */
hw_port_event(me, INT_PORT, 0);
+
+ /* Add periodic polling for this port, if it's not already going. */
+ if(controller->poll_event == NULL)
+ {
+ controller->poll_event = hw_event_queue_schedule (me, 1000,
+ tx3904sio_poll, NULL);
+
+ }
}
char* next_buf = zalloc(next_size);
memcpy(next_buf, fifo->buffer, fifo->used);
- if(fifo->buffer != NULL) zfree(fifo->buffer);
+ if(fifo->buffer != NULL) free(fifo->buffer);
fifo->buffer = next_buf;
fifo->size = next_size;
}
/* HW_TRACE ((me, "reset fifo")); */
fifo->used = 0;
fifo->size = 0;
- zfree(fifo->buffer);
+ free(fifo->buffer);
fifo->buffer = 0;
}
+void
+tx3904sio_poll(struct hw* me, void* ignored)
+{
+ struct tx3904sio* controller = hw_data (me);
+ tx3904sio_tickle (me);
+ hw_event_queue_deschedule (me, controller->poll_event);
+ controller->poll_event = hw_event_queue_schedule (me, 1000,
+ tx3904sio_poll, NULL);
+}
+
const struct hw_descriptor dv_tx3904sio_descriptor[] = {