diff options
-rw-r--r-- | hw/sh.h | 7 | ||||
-rw-r--r-- | hw/sh7750.c | 14 | ||||
-rw-r--r-- | hw/sh_serial.c | 33 |
3 files changed, 49 insertions, 5 deletions
@@ -35,7 +35,12 @@ void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq, /* sh_serial.c */ #define SH_SERIAL_FEAT_SCIF (1 << 0) void sh_serial_init (target_phys_addr_t base, int feat, - uint32_t freq, CharDriverState *chr); + uint32_t freq, CharDriverState *chr, + struct intc_source *eri_source, + struct intc_source *rxi_source, + struct intc_source *txi_source, + struct intc_source *tei_source, + struct intc_source *bri_source); /* tc58128.c */ int tc58128_init(struct SH7750State *s, char *zone1, char *zone2); diff --git a/hw/sh7750.c b/hw/sh7750.c index 158d030..a60a83b 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -556,9 +556,19 @@ SH7750State *sh7750_init(CPUSH4State * cpu) cpu->intc_handle = &s->intc; - sh_serial_init(0x1fe00000, 0, s->periph_freq, serial_hds[0]); + sh_serial_init(0x1fe00000, 0, s->periph_freq, serial_hds[0], + sh_intc_source(&s->intc, SCI1_ERI), + sh_intc_source(&s->intc, SCI1_RXI), + sh_intc_source(&s->intc, SCI1_TXI), + sh_intc_source(&s->intc, SCI1_TEI), + NULL); sh_serial_init(0x1fe80000, SH_SERIAL_FEAT_SCIF, - s->periph_freq, serial_hds[1]); + s->periph_freq, serial_hds[1], + sh_intc_source(&s->intc, SCIF_ERI), + sh_intc_source(&s->intc, SCIF_RXI), + sh_intc_source(&s->intc, SCIF_TXI), + NULL, + sh_intc_source(&s->intc, SCIF_BRI)); tmu012_init(0x1fd80000, TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK, diff --git a/hw/sh_serial.c b/hw/sh_serial.c index fe409c4..97601e5 100644 --- a/hw/sh_serial.c +++ b/hw/sh_serial.c @@ -55,6 +55,12 @@ typedef struct { int flags; CharDriverState *chr; + + struct intc_source *eri; + struct intc_source *rxi; + struct intc_source *txi; + struct intc_source *tei; + struct intc_source *bri; } sh_serial_state; static void sh_serial_ioport_write(void *opaque, uint32_t offs, uint32_t val) @@ -74,9 +80,15 @@ static void sh_serial_ioport_write(void *opaque, uint32_t offs, uint32_t val) s->brr = val; return; case 0x08: /* SCR */ - s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfb : 0xff); + s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfa : 0xff); if (!(val & (1 << 5))) s->flags |= SH_SERIAL_FLAG_TEND; + if ((s->feat & SH_SERIAL_FEAT_SCIF) && s->txi) { + if ((val & (1 << 7)) && !(s->txi->asserted)) + sh_intc_toggle_source(s->txi, 0, 1); + else if (!(val & (1 << 7)) && s->txi->asserted) + sh_intc_toggle_source(s->txi, 0, -1); + } return; case 0x0c: /* FTDR / TDR */ if (s->chr) { @@ -159,6 +171,12 @@ static uint32_t sh_serial_ioport_read(void *opaque, uint32_t offs) #endif if (s->feat & SH_SERIAL_FEAT_SCIF) { switch(offs) { + case 0x00: /* SMR */ + ret = s->smr; + break; + case 0x08: /* SCR */ + ret = s->scr; + break; case 0x10: /* FSR */ ret = 0; if (s->flags & SH_SERIAL_FLAG_TEND) @@ -278,7 +296,12 @@ static CPUWriteMemoryFunc *sh_serial_writefn[] = { }; void sh_serial_init (target_phys_addr_t base, int feat, - uint32_t freq, CharDriverState *chr) + uint32_t freq, CharDriverState *chr, + struct intc_source *eri_source, + struct intc_source *rxi_source, + struct intc_source *txi_source, + struct intc_source *tei_source, + struct intc_source *bri_source) { sh_serial_state *s; int s_io_memory; @@ -314,4 +337,10 @@ void sh_serial_init (target_phys_addr_t base, int feat, if (chr) qemu_chr_add_handlers(chr, sh_serial_can_receive1, sh_serial_receive1, sh_serial_event, s); + + s->eri = eri_source; + s->rxi = rxi_source; + s->txi = txi_source; + s->tei = tei_source; + s->bri = bri_source; } |