qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 2/2] 8250: Customized base baudrate


From: andrzej zaborowski
Subject: Re: [Qemu-devel] [PATCH 2/2] 8250: Customized base baudrate
Date: Mon, 14 Apr 2008 20:37:05 +0200

On 13/04/2008, Jan Kiszka <address@hidden> wrote:
> Previous patch revealed another issue of the 8250 emulation: The base
>  baudrate is assumed to be 115200. This is surely not correct and could
>  already cause wrong configurations if the virtual UART is forwarded to
>  real one. With the previous patch applied, a wrong baudbase is even more
>  problematic as it could lead to wrong throttling.
>
>  This patch extends serial[_mm]_init by a basebaud parameter and attempts
>  to fix all call sites - without claiming to be correct in all cases (I
>  tried to grab the information from current Linux). Please verify.
>
>  Signed-off-by: Jan Kiszka <address@hidden>
>  ---
>   hw/mips_jazz.c    |    4 ++--
>   hw/mips_malta.c   |    7 ++++---
>   hw/mips_mipssim.c |    2 +-
>   hw/mips_r4k.c     |    3 ++-
>   hw/omap1.c        |    3 ++-
>   hw/pc.c           |    3 ++-
>   hw/pc.h           |    7 ++++---
>   hw/ppc405_uc.c    |    2 +-
>   hw/ppc_chrp.c     |    2 +-
>   hw/ppc_oldworld.c |    2 +-
>   hw/ppc_prep.c     |    2 +-
>   hw/pxa2xx.c       |    6 ++++--
>   hw/serial.c       |   14 +++++++++-----
>   13 files changed, 34 insertions(+), 23 deletions(-)
>
>  Index: b/hw/serial.c
>  ===================================================================
>  --- a/hw/serial.c
>  +++ b/hw/serial.c
>  @@ -99,6 +99,7 @@ struct SerialState {
>      int last_break_enable;
>      target_phys_addr_t base;
>      int it_shift;
>  +    int baudbase;
>      QEMUTimer *tx_timer;
>      int tx_burst;
>      char tx_buf;
>  @@ -129,7 +130,7 @@ static void serial_tx_done(void *opaque)
>      if (s->tx_burst < 0) {
>          /* We assume 10 bits/char, OK for this purpose. */
>          s->tx_burst = THROTTLE_TX_INTERVAL * 1000 /
>  -            (1000000 * 10 / (115200 / s->divider));
>  +            (1000000 * 10 / (s->baudbase / s->divider));
>      }
>      s->thr_ipending = 1;
>      s->lsr |= UART_LSR_THRE;
>  @@ -161,7 +162,7 @@ static void serial_update_parameters(Ser
>      data_bits = (s->lcr & 0x03) + 5;
>      if (s->divider == 0)
>          return;
>  -    speed = 115200 / s->divider;
>  +    speed = s->baudbase / s->divider;
>      ssp.speed = speed;
>      ssp.parity = parity;
>      ssp.data_bits = data_bits;
>  @@ -407,7 +408,8 @@ static void serial_reset(void *opaque)
>   }
>
>   /* If fd is zero, it means that the serial device uses the console */
>  -SerialState *serial_init(int base, qemu_irq irq, CharDriverState *chr)
>  +SerialState *serial_init(int base, qemu_irq irq, int baudbase,
>  +                         CharDriverState *chr)
>   {
>      SerialState *s;
>
>  @@ -415,6 +417,7 @@ SerialState *serial_init(int base, qemu_
>      if (!s)
>          return NULL;
>      s->irq = irq;
>  +    s->baudbase = baudbase;
>
>      s->tx_timer = qemu_new_timer(vm_clock, serial_tx_done, s);
>      if (!s->tx_timer)
>  @@ -506,8 +509,8 @@ static CPUWriteMemoryFunc *serial_mm_wri
>   };
>
>   SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
>  -                             qemu_irq irq, CharDriverState *chr,
>  -                             int ioregister)
>  +                             qemu_irq irq, int baudbase,
>  +                             CharDriverState *chr, int ioregister)
>   {
>      SerialState *s;
>      int s_io_memory;
>  @@ -518,6 +521,7 @@ SerialState *serial_mm_init (target_phys
>      s->irq = irq;
>      s->base = base;
>      s->it_shift = it_shift;
>  +    s->baudbase= baudbase;
>
>      s->tx_timer = qemu_new_timer(vm_clock, serial_tx_done, s);
>      if (!s->tx_timer)
>  Index: b/hw/omap1.c
>  ===================================================================
>  --- a/hw/omap1.c
>  +++ b/hw/omap1.c
>  @@ -1734,7 +1734,8 @@ struct omap_uart_s *omap_uart_init(targe
>      struct omap_uart_s *s = (struct omap_uart_s *)
>              qemu_mallocz(sizeof(struct omap_uart_s));
>      if (chr)
>  -        s->serial = serial_mm_init(base, 2, irq, chr, 1);
>  +        s->serial =
>  +            serial_mm_init(base, 2, irq, omap_clk_getrate(clk)/16, chr, 1);

Yes, this should be correct.

>      return s;
>   }
>
>  Index: b/hw/pc.c
>  ===================================================================
>  --- a/hw/pc.c
>  +++ b/hw/pc.c
>  @@ -909,7 +909,8 @@ static void pc_init1(int ram_size, int v
>
>      for(i = 0; i < MAX_SERIAL_PORTS; i++) {
>          if (serial_hds[i]) {
>  -            serial_init(serial_io[i], i8259[serial_irq[i]], serial_hds[i]);
>  +            serial_init(serial_io[i], i8259[serial_irq[i]], 115200,
>  +                        serial_hds[i]);
>          }
>      }
>
>  Index: b/hw/pc.h
>  ===================================================================
>  --- a/hw/pc.h
>  +++ b/hw/pc.h
>  @@ -4,10 +4,11 @@
>
>   /* serial.c */
>
>  -SerialState *serial_init(int base, qemu_irq irq, CharDriverState *chr);
>  +SerialState *serial_init(int base, qemu_irq irq, int baudbase,
>  +                         CharDriverState *chr);
>   SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
>  -                             qemu_irq irq, CharDriverState *chr,
>  -                             int ioregister);
>  +                             qemu_irq irq, int baudbase,
>  +                             CharDriverState *chr, int ioregister);
>   uint32_t serial_mm_readb (void *opaque, target_phys_addr_t addr);
>   void serial_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t 
> value);
>   uint32_t serial_mm_readw (void *opaque, target_phys_addr_t addr);
>  Index: b/hw/pxa2xx.c
>  ===================================================================
>  --- a/hw/pxa2xx.c
>  +++ b/hw/pxa2xx.c
>  @@ -2077,7 +2077,8 @@ struct pxa2xx_state_s *pxa270_init(unsig
>      for (i = 0; pxa270_serial[i].io_base; i ++)
>          if (serial_hds[i])
>              serial_mm_init(pxa270_serial[i].io_base, 2,
>  -                            s->pic[pxa270_serial[i].irqn], serial_hds[i], 
> 1);
>  +                           s->pic[pxa270_serial[i].irqn], 14857000/16,
>  +                           serial_hds[i], 1);
>          else
>              break;
>      if (serial_hds[i])
>  @@ -2202,7 +2203,8 @@ struct pxa2xx_state_s *pxa255_init(unsig
>      for (i = 0; pxa255_serial[i].io_base; i ++)
>          if (serial_hds[i])
>              serial_mm_init(pxa255_serial[i].io_base, 2,
>  -                            s->pic[pxa255_serial[i].irqn], serial_hds[i], 
> 1);
>  +                           s->pic[pxa255_serial[i].irqn], 14745600/16,
>  +                           serial_hds[i], 1);

This also (although I, too, only know from looking at Linux code).

>          else
>              break;
>      if (serial_hds[i])
>  Index: b/hw/mips_jazz.c
>  ===================================================================
>  --- a/hw/mips_jazz.c
>  +++ b/hw/mips_jazz.c
>  @@ -234,9 +234,9 @@ void mips_jazz_init (int ram_size, int v
>
>      /* Serial ports */
>      if (serial_hds[0])
>  -        serial_mm_init(0x80006000, 0, rc4030[8], serial_hds[0], 1);
>  +        serial_mm_init(0x80006000, 0, rc4030[8], 8000000/16, serial_hds[0], 
> 1);
>      if (serial_hds[1])
>  -        serial_mm_init(0x80007000, 0, rc4030[9], serial_hds[1], 1);
>  +        serial_mm_init(0x80007000, 0, rc4030[9], 8000000/16, serial_hds[1], 
> 1);
>
>      /* Parallel port */
>      if (parallel_hds[0])
>  Index: b/hw/mips_malta.c
>  ===================================================================
>  --- a/hw/mips_malta.c
>  +++ b/hw/mips_malta.c
>  @@ -449,7 +449,8 @@ static MaltaFPGAState *malta_fpga_init(t
>
>      uart_chr = qemu_chr_open("vc");
>      qemu_chr_printf(uart_chr, "CBUS UART\r\n");
>  -    s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
>  +    s->uart =
>  +        serial_mm_init(base + 0x900, 3, env->irq[2], 230400, uart_chr, 1);
>
>      malta_fpga_reset(s);
>      qemu_register_reset(malta_fpga_reset, s);
>  @@ -918,9 +919,9 @@ void mips_malta_init (int ram_size, int
>      i8042_init(i8259[1], i8259[12], 0x60);
>      rtc_state = rtc_init(0x70, i8259[8]);
>      if (serial_hds[0])
>  -        serial_init(0x3f8, i8259[4], serial_hds[0]);
>  +        serial_init(0x3f8, i8259[4], 115200, serial_hds[0]);
>      if (serial_hds[1])
>  -        serial_init(0x2f8, i8259[3], serial_hds[1]);
>  +        serial_init(0x2f8, i8259[3], 115200, serial_hds[1]);
>      if (parallel_hds[0])
>          parallel_init(0x378, i8259[7], parallel_hds[0]);
>      for(i = 0; i < MAX_FD; i++) {
>  Index: b/hw/mips_mipssim.c
>  ===================================================================
>  --- a/hw/mips_mipssim.c
>  +++ b/hw/mips_mipssim.c
>  @@ -174,7 +174,7 @@ mips_mipssim_init (int ram_size, int vga
>      /* A single 16450 sits at offset 0x3f8. It is attached to
>         MIPS CPU INT2, which is interrupt 4. */
>      if (serial_hds[0])
>  -        serial_init(0x3f8, env->irq[4], serial_hds[0]);
>  +        serial_init(0x3f8, env->irq[4], 115200, serial_hds[0]);
>
>      if (nd_table[0].vlan) {
>          if (nd_table[0].model == NULL
>  Index: b/hw/mips_r4k.c
>  ===================================================================
>  --- a/hw/mips_r4k.c
>  +++ b/hw/mips_r4k.c
>  @@ -229,7 +229,8 @@ void mips_r4k_init (int ram_size, int vg
>
>      for(i = 0; i < MAX_SERIAL_PORTS; i++) {
>          if (serial_hds[i]) {
>  -            serial_init(serial_io[i], i8259[serial_irq[i]], serial_hds[i]);
>  +            serial_init(serial_io[i], i8259[serial_irq[i]], 115200,
>  +                        serial_hds[i]);
>          }
>      }
>
>  Index: b/hw/ppc405_uc.c
>  ===================================================================
>  --- a/hw/ppc405_uc.c
>  +++ b/hw/ppc405_uc.c
>  @@ -1223,7 +1223,7 @@ void ppc405_serial_init (CPUState *env,
>   #ifdef DEBUG_SERIAL
>      printf("%s: offset " PADDRX "\n", __func__, offset);
>   #endif
>  -    serial = serial_mm_init(offset, 0, irq, chr, 0);
>  +    serial = serial_mm_init(offset, 0, irq, 399193, chr, 0);
>      ppc4xx_mmio_register(env, mmio, offset, 0x008,
>                           serial_mm_read, serial_mm_write, serial);
>   }
>  Index: b/hw/ppc_chrp.c
>  ===================================================================
>  --- a/hw/ppc_chrp.c
>  +++ b/hw/ppc_chrp.c
>  @@ -264,7 +264,7 @@ static void ppc_core99_init (int ram_siz
>      dummy_irq = i8259_init(NULL);
>
>      /* XXX: use Mac Serial port */
>  -    serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
>  +    serial_init(0x3f8, dummy_irq[4], 115200, serial_hds[0]);
>      for(i = 0; i < nb_nics; i++) {
>          if (!nd_table[i].model)
>              nd_table[i].model = "ne2k_pci";
>  Index: b/hw/ppc_oldworld.c
>  ===================================================================
>  --- a/hw/ppc_oldworld.c
>  +++ b/hw/ppc_oldworld.c
>  @@ -287,7 +287,7 @@ static void ppc_heathrow_init (int ram_s
>      dummy_irq = i8259_init(NULL);
>
>      /* XXX: use Mac Serial port */
>  -    serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
>  +    serial_init(0x3f8, dummy_irq[4], 115200, serial_hds[0]);
>
>      for(i = 0; i < nb_nics; i++) {
>          if (!nd_table[i].model)
>  Index: b/hw/ppc_prep.c
>  ===================================================================
>  --- a/hw/ppc_prep.c
>  +++ b/hw/ppc_prep.c
>  @@ -667,7 +667,7 @@ static void ppc_prep_init (int ram_size,
>      //    pit = pit_init(0x40, i8259[0]);
>      rtc_init(0x70, i8259[8]);
>
>  -    serial_init(0x3f8, i8259[4], serial_hds[0]);
>  +    serial_init(0x3f8, i8259[4], 115200, serial_hds[0]);
>      nb_nics1 = nb_nics;
>      if (nb_nics1 > NE2000_NB_MAX)
>          nb_nics1 = NE2000_NB_MAX;
>
>
>


-- 
Please do not print this email unless absolutely necessary. Spread
environmental awareness.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]