SH4 serial controler improvements.
PATCH RESEND 2/2 SH4 serial controler improvements.
This patch avoids some assertion error and makes the message from init process printed out to the console.
It does:
- makes SMR & SCR registers readable
- adds TXI interrupt handling
- fixes SCR register write mask
Patch it after patch 1/2, or offset warning happens.
hw/sh.h +6 -1
@@ -35,7 +35,12 @@/* 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);
hw/sh7750.c +12 -2
@@ -556,9 +556,19 @@ 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,
hw/sh_serial.c +31 -2
@@ -55,6 +55,12 @@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 @@ 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 @@#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 @@ };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 @@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; }