diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-12-05 20:31:52 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-12-05 20:31:52 +0000 |
commit | ba3c64fb476d57c35013970ac444f04f35893ca9 (patch) | |
tree | ef1a50165c32cf861862c94cfd9bcf9ebffcd9f2 /hw/slavio_serial.c | |
parent | b9788fc4c4974a4871e0ee46b5c06fee105a6aff (diff) |
Initial SPARC SMP support (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1694 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/slavio_serial.c')
-rw-r--r-- | hw/slavio_serial.c | 72 |
1 files changed, 56 insertions, 16 deletions
diff --git a/hw/slavio_serial.c b/hw/slavio_serial.c index de45cc5de1..2b89c6d62a 100644 --- a/hw/slavio_serial.c +++ b/hw/slavio_serial.c @@ -45,6 +45,8 @@ #ifdef DEBUG_SERIAL #define SER_DPRINTF(fmt, args...) \ do { printf("SER: " fmt , ##args); } while (0) +#define pic_set_irq(irq, level) \ +do { printf("SER: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0) #else #define SER_DPRINTF(fmt, args...) #endif @@ -174,6 +176,50 @@ static void slavio_serial_reset(void *opaque) slavio_serial_reset_chn(&s->chn[1]); } +static inline void clr_rxint(ChannelState *s) +{ + s->rxint = 0; + if (s->chn == 0) + s->rregs[3] &= ~0x20; + else { + s->otherchn->rregs[3] &= ~4; + } + slavio_serial_update_irq(s); +} + +static inline void set_rxint(ChannelState *s) +{ + s->rxint = 1; + if (s->chn == 0) + s->rregs[3] |= 0x20; + else { + s->otherchn->rregs[3] |= 4; + } + slavio_serial_update_irq(s); +} + +static inline void clr_txint(ChannelState *s) +{ + s->txint = 0; + if (s->chn == 0) + s->rregs[3] &= ~0x10; + else { + s->otherchn->rregs[3] &= ~2; + } + slavio_serial_update_irq(s); +} + +static inline void set_txint(ChannelState *s) +{ + s->txint = 1; + if (s->chn == 0) + s->rregs[3] |= 0x10; + else { + s->otherchn->rregs[3] |= 2; + } + slavio_serial_update_irq(s); +} + static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) { SerialState *ser = opaque; @@ -198,10 +244,14 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint newreg |= 0x8; break; case 0x20: - s->rxint = 0; + clr_rxint(s); break; case 0x28: - s->txint = 0; + clr_txint(s); + break; + case 0x38: + clr_rxint(s); + clr_txint(s); break; default: break; @@ -247,12 +297,7 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint s->txint = 1; s->rregs[0] |= 4; // Tx buffer empty s->rregs[1] |= 1; // All sent - // Interrupts reported only on channel A - if (s->chn == 0) - s->rregs[3] |= 0x10; - else { - s->otherchn->rregs[3] |= 2; - } + set_txint(s); slavio_serial_update_irq(s); } break; @@ -280,6 +325,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr) return ret; case 1: s->rregs[0] &= ~1; + clr_rxint(s); if (s->type == kbd) ret = get_queue(s); else @@ -304,16 +350,10 @@ static int serial_can_receive(void *opaque) static void serial_receive_byte(ChannelState *s, int ch) { + SER_DPRINTF("put ch %d\n", ch); s->rregs[0] |= 1; - // Interrupts reported only on channel A - if (s->chn == 0) - s->rregs[3] |= 0x20; - else { - s->otherchn->rregs[3] |= 4; - } s->rx = ch; - s->rxint = 1; - slavio_serial_update_irq(s); + set_rxint(s); } static void serial_receive_break(ChannelState *s) |