qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] Re: [PATCH] Always swap endianness in DBDMA


From: Aurelien Jarno
Subject: [Qemu-devel] Re: [PATCH] Always swap endianness in DBDMA
Date: Wed, 23 Dec 2009 07:12:11 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

On Tue, Dec 22, 2009 at 02:45:17PM +0100, Alexander Graf wrote:
> When we get an MMIO request, we always get variables in host endianness. The
> only time we need to actually reverse byte order is when we read bytes from
> guest memory.
> 
> Apparently the DBDMA implementation is different there. A lot of the logic
> in there depends on values being big endian. Now, qemu does all the conversion
> in the MMIO handlers for us already though, so it turns out that we're in
> the same byte order from a C point of view, but cpu_to_be32 and be32_to_cpu
> end up being nops.
> 
> This makes the code work differently on x86 (little endian) than on ppc (big
> endian). On x86 it works, on ppc it doesn't.
> 
> This patch (while being seriously hacky and ugly) makes dbdma emulation work
> on ppc hosts. I'll leave the real fixing to someone else.

I have to say I found it too hacky to be included in QEMU. I would
prefer if someone can provide a real fix.

> Signed-off-by: Alexander Graf <address@hidden>
> CC: Laurent Vivier <address@hidden>
> 
> ---
> 
> V1 -> V2:
> 
>   - s/cpu_to_be32/dbdma_cpu_to_be32/g
>   - s/be32_to_cpu/dbdma_be32_to_cpu/g
> ---
>  hw/mac_dbdma.c |   86 ++++++++++++++++++++++++++++++-------------------------
>  1 files changed, 47 insertions(+), 39 deletions(-)
> 
> diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
> index 98dccfd..555983a 100644
> --- a/hw/mac_dbdma.c
> +++ b/hw/mac_dbdma.c
> @@ -40,6 +40,14 @@
>  #include "isa.h"
>  #include "mac_dbdma.h"
>  
> +/*
> + * XXX This is just plain wrong. Apparently we don't want to have big endian
> + *     values, but reversed endian ones. The code as is doesn't work on big
> + *     endian hosts. With these defines it does.
> + */
> +#define dbdma_cpu_to_be32 bswap32
> +#define dbdma_be32_to_cpu bswap32
> +
>  /* debug DBDMA */
>  //#define DEBUG_DBDMA
>  
> @@ -184,19 +192,19 @@ static void dump_dbdma_cmd(dbdma_cmd *cmd)
>  static void dbdma_cmdptr_load(DBDMA_channel *ch)
>  {
>      DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",
> -                  be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));
> -    cpu_physical_memory_read(be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),
> +                  dbdma_be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));
> +    cpu_physical_memory_read(dbdma_be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),
>                               (uint8_t*)&ch->current, sizeof(dbdma_cmd));
>  }
>  
>  static void dbdma_cmdptr_save(DBDMA_channel *ch)
>  {
>      DBDMA_DPRINTF("dbdma_cmdptr_save 0x%08x\n",
> -                  be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));
> +                  dbdma_be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));
>      DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n",
>                    le16_to_cpu(ch->current.xfer_status),
>                    le16_to_cpu(ch->current.res_count));
> -    cpu_physical_memory_write(be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),
> +    cpu_physical_memory_write(dbdma_be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),
>                                (uint8_t*)&ch->current, sizeof(dbdma_cmd));
>  }
>  
> @@ -204,8 +212,8 @@ static void kill_channel(DBDMA_channel *ch)
>  {
>      DBDMA_DPRINTF("kill_channel\n");
>  
> -    ch->regs[DBDMA_STATUS] |= cpu_to_be32(DEAD);
> -    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~ACTIVE);
> +    ch->regs[DBDMA_STATUS] |= dbdma_cpu_to_be32(DEAD);
> +    ch->regs[DBDMA_STATUS] &= dbdma_cpu_to_be32(~ACTIVE);
>  
>      qemu_irq_raise(ch->irq);
>  }
> @@ -230,10 +238,10 @@ static void conditional_interrupt(DBDMA_channel *ch)
>          return;
>      }
>  
> -    status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
> +    status = dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
>  
> -    sel_mask = (be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) >> 16) & 0x0f;
> -    sel_value = be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) & 0x0f;
> +    sel_mask = (dbdma_be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) >> 16) & 0x0f;
> +    sel_value = dbdma_be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) & 0x0f;
>  
>      cond = (status & sel_mask) == (sel_value & sel_mask);
>  
> @@ -268,10 +276,10 @@ static int conditional_wait(DBDMA_channel *ch)
>          return 1;
>      }
>  
> -    status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
> +    status = dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
>  
> -    sel_mask = (be32_to_cpu(ch->regs[DBDMA_WAIT_SEL]) >> 16) & 0x0f;
> -    sel_value = be32_to_cpu(ch->regs[DBDMA_WAIT_SEL]) & 0x0f;
> +    sel_mask = (dbdma_be32_to_cpu(ch->regs[DBDMA_WAIT_SEL]) >> 16) & 0x0f;
> +    sel_value = dbdma_be32_to_cpu(ch->regs[DBDMA_WAIT_SEL]) & 0x0f;
>  
>      cond = (status & sel_mask) == (sel_value & sel_mask);
>  
> @@ -292,10 +300,10 @@ static void next(DBDMA_channel *ch)
>  {
>      uint32_t cp;
>  
> -    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~BT);
> +    ch->regs[DBDMA_STATUS] &= dbdma_cpu_to_be32(~BT);
>  
> -    cp = be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]);
> -    ch->regs[DBDMA_CMDPTR_LO] = cpu_to_be32(cp + sizeof(dbdma_cmd));
> +    cp = dbdma_be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]);
> +    ch->regs[DBDMA_CMDPTR_LO] = dbdma_cpu_to_be32(cp + sizeof(dbdma_cmd));
>      dbdma_cmdptr_load(ch);
>  }
>  
> @@ -304,7 +312,7 @@ static void branch(DBDMA_channel *ch)
>      dbdma_cmd *current = &ch->current;
>  
>      ch->regs[DBDMA_CMDPTR_LO] = current->cmd_dep;
> -    ch->regs[DBDMA_STATUS] |= cpu_to_be32(BT);
> +    ch->regs[DBDMA_STATUS] |= dbdma_cpu_to_be32(BT);
>      dbdma_cmdptr_load(ch);
>  }
>  
> @@ -331,10 +339,10 @@ static void conditional_branch(DBDMA_channel *ch)
>          return;
>      }
>  
> -    status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
> +    status = dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;
>  
> -    sel_mask = (be32_to_cpu(ch->regs[DBDMA_BRANCH_SEL]) >> 16) & 0x0f;
> -    sel_value = be32_to_cpu(ch->regs[DBDMA_BRANCH_SEL]) & 0x0f;
> +    sel_mask = (dbdma_be32_to_cpu(ch->regs[DBDMA_BRANCH_SEL]) >> 16) & 0x0f;
> +    sel_value = dbdma_be32_to_cpu(ch->regs[DBDMA_BRANCH_SEL]) & 0x0f;
>  
>      cond = (status & sel_mask) == (sel_value & sel_mask);
>  
> @@ -365,19 +373,19 @@ static void dbdma_end(DBDMA_io *io)
>      if (conditional_wait(ch))
>          goto wait;
>  
> -    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
> -    current->res_count = cpu_to_le16(be32_to_cpu(io->len));
> +    current->xfer_status = 
> cpu_to_le16(dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]));
> +    current->res_count = cpu_to_le16(dbdma_be32_to_cpu(io->len));
>      dbdma_cmdptr_save(ch);
>      if (io->is_last)
> -        ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
> +        ch->regs[DBDMA_STATUS] &= dbdma_cpu_to_be32(~FLUSH);
>  
>      conditional_interrupt(ch);
>      conditional_branch(ch);
>  
>  wait:
>      ch->processing = 0;
> -    if ((ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN)) &&
> -        (ch->regs[DBDMA_STATUS] & cpu_to_be32(ACTIVE)))
> +    if ((ch->regs[DBDMA_STATUS] & dbdma_cpu_to_be32(RUN)) &&
> +        (ch->regs[DBDMA_STATUS] & dbdma_cpu_to_be32(ACTIVE)))
>          channel_run(ch);
>  }
>  
> @@ -456,9 +464,9 @@ static void load_word(DBDMA_channel *ch, int key, 
> uint32_t addr,
>      if (conditional_wait(ch))
>          goto wait;
>  
> -    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
> +    current->xfer_status = 
> cpu_to_le16(dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]));
>      dbdma_cmdptr_save(ch);
> -    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
> +    ch->regs[DBDMA_STATUS] &= dbdma_cpu_to_be32(~FLUSH);
>  
>      conditional_interrupt(ch);
>      next(ch);
> @@ -494,9 +502,9 @@ static void store_word(DBDMA_channel *ch, int key, 
> uint32_t addr,
>      if (conditional_wait(ch))
>          goto wait;
>  
> -    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
> +    current->xfer_status = 
> cpu_to_le16(dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]));
>      dbdma_cmdptr_save(ch);
> -    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
> +    ch->regs[DBDMA_STATUS] &= dbdma_cpu_to_be32(~FLUSH);
>  
>      conditional_interrupt(ch);
>      next(ch);
> @@ -512,7 +520,7 @@ static void nop(DBDMA_channel *ch)
>      if (conditional_wait(ch))
>          goto wait;
>  
> -    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
> +    current->xfer_status = 
> cpu_to_le16(dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]));
>      dbdma_cmdptr_save(ch);
>  
>      conditional_interrupt(ch);
> @@ -524,7 +532,7 @@ wait:
>  
>  static void stop(DBDMA_channel *ch)
>  {
> -    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~(ACTIVE|DEAD|FLUSH));
> +    ch->regs[DBDMA_STATUS] &= dbdma_cpu_to_be32(~(ACTIVE|DEAD|FLUSH));
>  
>      /* the stop command does not increment command pointer */
>  }
> @@ -541,7 +549,7 @@ static void channel_run(DBDMA_channel *ch)
>  
>      /* clear WAKE flag at command fetch */
>  
> -    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~WAKE);
> +    ch->regs[DBDMA_STATUS] &= dbdma_cpu_to_be32(~WAKE);
>  
>      cmd = le16_to_cpu(current->command) & COMMAND_MASK;
>  
> @@ -618,7 +626,7 @@ static void DBDMA_run (DBDMA_channel *ch)
>      int channel;
>  
>      for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) {
> -            uint32_t status = be32_to_cpu(ch->regs[DBDMA_STATUS]);
> +            uint32_t status = dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]);
>              if (!ch->processing && (status & RUN) && (status & ACTIVE))
>                  channel_run(ch);
>      }
> @@ -660,12 +668,12 @@ dbdma_control_write(DBDMA_channel *ch)
>      uint16_t mask, value;
>      uint32_t status;
>  
> -    mask = (be32_to_cpu(ch->regs[DBDMA_CONTROL]) >> 16) & 0xffff;
> -    value = be32_to_cpu(ch->regs[DBDMA_CONTROL]) & 0xffff;
> +    mask = (dbdma_be32_to_cpu(ch->regs[DBDMA_CONTROL]) >> 16) & 0xffff;
> +    value = dbdma_be32_to_cpu(ch->regs[DBDMA_CONTROL]) & 0xffff;
>  
>      value &= (RUN | PAUSE | FLUSH | WAKE | DEVSTAT);
>  
> -    status = be32_to_cpu(ch->regs[DBDMA_STATUS]);
> +    status = dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]);
>  
>      status = (value & mask) | (status & ~mask);
>  
> @@ -677,14 +685,14 @@ dbdma_control_write(DBDMA_channel *ch)
>      }
>      if (status & PAUSE)
>          status &= ~ACTIVE;
> -    if ((be32_to_cpu(ch->regs[DBDMA_STATUS]) & RUN) && !(status & RUN)) {
> +    if ((dbdma_be32_to_cpu(ch->regs[DBDMA_STATUS]) & RUN) && !(status & 
> RUN)) {
>          /* RUN is cleared */
>          status &= ~(ACTIVE|DEAD);
>      }
>  
>      DBDMA_DPRINTF("    status 0x%08x\n", status);
>  
> -    ch->regs[DBDMA_STATUS] = cpu_to_be32(status);
> +    ch->regs[DBDMA_STATUS] = dbdma_cpu_to_be32(status);
>  
>      if (status & ACTIVE)
>          qemu_bh_schedule(dbdma_bh);
> @@ -706,7 +714,7 @@ static void dbdma_writel (void *opaque,
>      /* cmdptr cannot be modified if channel is RUN or ACTIVE */
>  
>      if (reg == DBDMA_CMDPTR_LO &&
> -        (ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN | ACTIVE)))
> +        (ch->regs[DBDMA_STATUS] & dbdma_cpu_to_be32(RUN | ACTIVE)))
>       return;
>  
>      ch->regs[reg] = value;
> @@ -717,7 +725,7 @@ static void dbdma_writel (void *opaque,
>          break;
>      case DBDMA_CMDPTR_LO:
>          /* 16-byte aligned */
> -        ch->regs[DBDMA_CMDPTR_LO] &= cpu_to_be32(~0xf);
> +        ch->regs[DBDMA_CMDPTR_LO] &= dbdma_cpu_to_be32(~0xf);
>          dbdma_cmdptr_load(ch);
>          break;
>      case DBDMA_STATUS:
> -- 
> 1.6.0.2
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
address@hidden                 http://www.aurel32.net




reply via email to

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