qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] Ping [PATCH 0/2] Add TPCI200 and IP-Octal 232 IndustryP


From: Alberto Garcia
Subject: Re: [Qemu-devel] Ping [PATCH 0/2] Add TPCI200 and IP-Octal 232 IndustryPack emulation
Date: Wed, 10 Oct 2012 19:59:54 +0200
User-agent: Mutt/1.5.20 (2009-06-14)

On Wed, Oct 10, 2012 at 01:35:06PM +0200, Avi Kivity wrote:

> > Hey, I finally found some time to look into this, the problem that
> > I see is that the PCI carrier doesn't just map each space into its
> > local address spaces, in addition to that:
> > 
> >   1) it changes the data and addresses according to the endianness
> >      configuration in the local configuration registers (PCI
> >      BAR0).  See adjust_addr()/adjust_value() and page 20 of the
> >      user manual.
> > 
> >      http://www.tews.com/Products/ArticleGroup/TPCI/TPCI200.html
> 
> This is supported (albeit not cleanly) by the memory
> API.  There is the MemoryRegionOps::endianess attribute,
> you can have a mem16_be_space and mem16_le_space; use
> memory_region_add_subregion()/memory_region_del_subregion() to map
> le_space or be_space as needed to the BAR.

I'm not sure if that will work in this case. From the TPCI200 manual:

  "Changing Local Space 0, 1 or 2 to Big Endian mode results in swapped
   data lines of the local bus:

   A 32 bit access is separated by the PCI9030 into two local 16 bit
   accesses. Byte lane 0 and 1 are swapped, and byte lane 2 and 3 are
   swapped.

   During 16 bit access, the upper and lower bytes are displayed in
   reverse order.

   During 8 bit access odd and even addresses are swapped. To access
   Address 0x00, the Address 0x01 must be used. An access to Address
   0x01 is done by Address 0x00."

32 bit access does not worry me in this case, since it's not used in
any local space, but how about 8 bit access? Is the "FIXME: big-endian
support" in access_with_adjusted_size() related to this?

> >   2) read accesses to the local address space 1 are also used to
> >      acknowledge interrupts (manual page 33 and
> >      tpci200_read_las1()).
> 
> You can map a small subregion over those addresses.  What is the
> value read? does it need to go to the int space and read it, or is
> it some fixed value?

It needs to go to the int space.

> > memory_region_init_ram_ptr(&s->mmio, "tpci200_mmio", 128, s->local_cfg);
> > memory_region_init_alias(&s->io, "tpci200_io", &s->mmio, 0, 128);
> > pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
> > pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO,     &s->io);

> This is supposed to work.  What does 'info mtree' show?

pci
0000000000000000-7ffffffffffffffe (prio 0, RW): pci
[...]
  00000000fb022000-00000000fb02207f (prio 1, RW): tpci200_mmio
  00000000fb023000-00000000fb0230ff (prio 1, RW): tpci200_las0
  00000000fb024000-00000000fb0243ff (prio 1, RW): tpci200_las1
[...]

tpci200_mmio
00000000fb022000-00000000fb02207f (prio 1, RW): tpci200_mmio



I also tried to debug a bit read accesses to that memory region to see
what was going on. For example, when the kernel driver tries to read
the config register at PCI BAR0 + 0x2C the call ends up here:

subpage_ram_read (opaque=0x0, addr=0x2C, size=4)

I don't know the internals of the memory handling in QEMU but that
call doesn't look right, and the returned valued is indeed wrong.

> What happens if you grow the size up to a page size?

So I changed the size to 4K and got this:

kvm_set_phys_mem: error registering slot: Invalid argument
Aborted

If I run qemu without -enable-kvm then it appears to work fine (not
with the 128 bytes memory region, though).

> Do both BARs fail, or just the IO BAR?

I think the kernel driver doesn't use the IO BAR at all, so all my
tests are with BAR0.

Berto



reply via email to

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