diff mbox

e500 ATMU register reads broken

Message ID 55CDD5E2.60405@sysgo.com
State New
Headers show

Commit Message

Rudolf Marek Aug. 14, 2015, 11:49 a.m. UTC
Hi all,

I noticed that ATMU register reads on E500 are broken. Due to the wrong mask, 
some registers cannot be read and instead some other registers are read. Please 
see attached patch which fixes the problem.

I also noticed that if there was an intention to have 1:1 PCI/CPU space mapping 
for 0xC000_0000 for MPC8544DS without programming ATMUs - it does not work, 
unless ATMUs are programmed.

Signed-off-by: Rudolf Marek <rudolf.marek@sysgo.com>

Thanks,
Rudolf

Comments

Rudolf Marek Aug. 21, 2015, 12:33 p.m. UTC | #1
Hi all,

Ping?

Thanks
Rudolf

Dne 14.8.2015 v 13:49 Rudolf Marek napsal(a):
> Hi all,
>
> I noticed that ATMU register reads on E500 are broken. Due to the wrong mask,
> some registers cannot be read and instead some other registers are read. Please
> see attached patch which fixes the problem.
>
> I also noticed that if there was an intention to have 1:1 PCI/CPU space mapping
> for 0xC000_0000 for MPC8544DS without programming ATMUs - it does not work,
> unless ATMUs are programmed.
>
> Signed-off-by: Rudolf Marek <rudolf.marek@sysgo.com>
>
> Thanks,
> Rudolf
>
Alexander Graf Aug. 26, 2015, 9:15 a.m. UTC | #2
On 21.08.15 14:33, Rudolf Marek wrote:
> Hi all,
> 
> Ping?
> 
> Thanks
> Rudolf
> 
> Dne 14.8.2015 v 13:49 Rudolf Marek napsal(a):
>> Hi all,
>>
>> I noticed that ATMU register reads on E500 are broken. Due to the
>> wrong mask,
>> some registers cannot be read and instead some other registers are
>> read. Please
>> see attached patch which fixes the problem.

Sorry for the long delay. Please CC qemu-ppc@nongnu.org on the next
submission, so that more PPC people have the chance to review the patch ;).

Thanks, applied to ppc-next.

>>
>> I also noticed that if there was an intention to have 1:1 PCI/CPU
>> space mapping
>> for 0xC000_0000 for MPC8544DS without programming ATMUs - it does not
>> work,
>> unless ATMUs are programmed.

I've received a report about this on IRC as well. It works fine with
U-Boot because that writes the ATMUs, but not with direct -kernel boot.

Would you mind to follow up with a patch to the mpc8544ds machine file
that programs the ATMUs on init?


Thanks a lot!

Alex
Rudolf Marek Aug. 28, 2015, 7:22 a.m. UTC | #3
Hi all,

 > Sorry for the long delay. Please CC qemu-ppc@nongnu.org on the next
> submission, so that more PPC people have the chance to review the patch ;).

I see, I missed this mailing list -
http://wiki.qemu.org/Contribute/SubmitAPatch

As it do not not mention it.

> Thanks, applied to ppc-next.

Thanks! Will it be part of 2.4.x ?

> Would you mind to follow up with a patch to the mpc8544ds machine file
> that programs the ATMUs on init?

I also use -kernel option.

Hm I don't know how to program it in QEMU internally, what I'm currently doing 
in my code is bellow.

The PCI_IO and PCI_MEM are the addresses of the translation windows in CPU 
space. I guess you can set them to match MPC8544ds Here is my current WIP code 
to do it:

   /* Disable all translations */
     pit[0].war = 0;
     pit[1].war = 0;
     pit[2].war = 0;

     pot[0].war = 0;
     pot[1].war = 0;
     pot[2].war = 0;
     pot[3].war = 0;
     pot[4].war = 0;
     __asm__ volatile ("eieio");

     /* setup the PCI inbound window 1:1 for first 2GB */
     pit[0].war = 0;
     pit[0].ar = 0;
     pit[0].war = 0;
     pit[0].wbear = 0;
     /* 2^31 is 2GB, it is -1 encoded as 30 */
     pit[0].war = PIWAR_EN |  PIWAR_PF | PIWAR_LOCAL |
                  PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | 30;

     /* setup the outbound translation as 1:1 256M */
     pot[1].war = 0;
     pot[1].ear = 0;
     /* 2^28 is 256M it is -1 encoded as 27 */
     pot[1].wbar = (PCI_MEM >> 12) & 0x000fffff;
     pot[1].ar = (PCI_MEM >> 12) & 0x000fffff;
     __asm__ volatile ("eieio");
     pot[1].war = POWAR_EN | POWAR_MEM_READ | POWAR_MEM_WRITE | 27;

     /* Outbound IO port window size of window is 64K */
     pot[2].war = 0;
     pot[2].ear = 0;
     pot[2].wbar = (PCI_IO >> 12) & 0x000fffff;
     pot[2].ar = 0;
     __asm__ volatile ("eieio");
     /* 2^16 is 64K it is -1 encoded as 15 */
     pot[2].war = POWAR_EN | POWAR_IO_READ | POWAR_IO_WRITE | 15;

It programs the 1:1 PCI to CPU for 2GB of RAM. And it programs the PCI MMIO 
window 1:1 with start PCI_MEM size 256M and it places the i/o ports at PCI_IO.

In theory you should also enable the MEM decoder of the PCI root device, but I 
think QEMU does not need it (see u-boot what it is doing).

Feel free to use this code as a template for the QEMU support,

Thanks
Rudolf

-
S přátelským pozdravem / Best regards / Mit freundlichen Grüßen

Ing. Rudolf Marek
SYSGO s.r.o.
Zelený pruh 99
CZ-14800 Praha 4
Phone: +420 222138 111, +49 6136 9948 111
Fax: +420 296374890, +49 6136 9948 1 111
rudolf.marek@sysgo.com

http://www.sysgo.com | http://www.elinos.com | http://www.pikeos.com
diff mbox

Patch

From 75795e2bcc6ffbb245d192eb84e063d855dbf248 Mon Sep 17 00:00:00 2001
From: Rudolf Marek <mar@sysgo.com>
Date: Fri, 14 Aug 2015 13:38:55 +0200
Subject: [PATCH] PPC: e500 pci host: Fix ATMUs register reads

There is a bug in the register mask when reading
the ATMUs registers. As the result some registers
cannot be read, and read is aliased to the other
registers. Fix it.

Signed-off-by: Rudolf Marek <rudolf.marek@sysgo.com>
---
 hw/pci-host/ppce500.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 613ba73..50add34 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -140,7 +140,7 @@  static uint64_t pci_reg_read4(void *opaque, hwaddr addr,
     case PPCE500_PCI_OW3:
     case PPCE500_PCI_OW4:
         idx = (addr >> 5) & 0x7;
-        switch (addr & 0xC) {
+        switch (addr & 0x1F) {
         case PCI_POTAR:
             value = pci->pob[idx].potar;
             break;
@@ -162,7 +162,7 @@  static uint64_t pci_reg_read4(void *opaque, hwaddr addr,
     case PPCE500_PCI_IW2:
     case PPCE500_PCI_IW1:
         idx = ((addr >> 5) & 0x3) - 1;
-        switch (addr & 0xC) {
+        switch (addr & 0x1F) {
         case PCI_PITAR:
             value = pci->pib[idx].pitar;
             break;
-- 
1.9.1