X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fmips%2Fdv-tx3904sio.c;h=24b96c07b2af6c2ce6a4a75bcbac68f0f7d49668;hb=d5fb0879a5c2008b43d057d7a0ee09bb3b500be2;hp=405f072a7aee29e789abf6e388cfddf37aa66ab8;hpb=e98fe4f7b54cbdf29aef9287bbb1bea8801dd05a;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/mips/dv-tx3904sio.c b/sim/mips/dv-tx3904sio.c index 405f072a7a..24b96c07b2 100644 --- a/sim/mips/dv-tx3904sio.c +++ b/sim/mips/dv-tx3904sio.c @@ -1,6 +1,6 @@ /* This file is part of the program GDB, the GNU debugger. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2007 Free Software Foundation, Inc. Contributed by Cygnus Solutions. This program is free software; you can redistribute it and/or modify @@ -23,7 +23,7 @@ #include "sim-main.h" #include "hw-main.h" #include "dv-sockser.h" - +#include "sim-assert.h" /* DEVICE @@ -97,7 +97,7 @@ static int tx3904sio_fifo_nonempty(struct hw*, struct tx3904sio_fifo*); 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 */ @@ -167,6 +167,7 @@ struct tx3904sio 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) @@ -180,6 +181,9 @@ struct tx3904sio 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; }; @@ -261,6 +265,7 @@ tx3904sio_finish (struct hw *me) = controller->sbgr = 0; controller->slcr = 0x40000000; /* set TWUB */ controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */ + controller->poll_event = NULL; } @@ -289,6 +294,7 @@ tx3904sio_port_event (struct hw *me, = controller->sbgr = 0; controller->slcr = 0x40000000; /* set TWUB */ controller->sbgr = 0x03ff0000; /* set BCLK=3, BRD=FF */ + /* Don't interfere with I/O poller. */ break; } @@ -320,7 +326,7 @@ tx3904sio_io_read_buffer (struct hw *me, { 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 */ @@ -335,7 +341,7 @@ tx3904sio_io_read_buffer (struct hw *me, 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; @@ -344,6 +350,8 @@ tx3904sio_io_read_buffer (struct hw *me, } /* 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); } @@ -370,7 +378,7 @@ tx3904sio_io_write_buffer (struct hw *me, 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) @@ -412,7 +420,7 @@ tx3904sio_io_write_buffer (struct hw *me, 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; @@ -498,6 +506,7 @@ tx3904sio_tickle(struct hw *me) { 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)); } @@ -529,6 +538,14 @@ tx3904sio_tickle(struct hw *me) 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); + + } } @@ -587,6 +604,16 @@ tx3904sio_fifo_reset(struct hw* me, struct tx3904sio_fifo* fifo) } +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[] = {