Re: [PATCH v1 3/5] contrib/gitdm: add Andrey to the individual group

2019-10-14 Thread Andrey Smirnov
On Mon, Oct 14, 2019 at 6:59 AM Alex Bennée  wrote:
>
> Please confirm this is the correct section for you.
>

I think this is. Here's

Acked-by: Andrey Smirnov 

in case that's needed.

> Signed-off-by: Alex Bennée 
> Cc: Andrey Smirnov 
> ---
>  contrib/gitdm/group-map-individuals | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/contrib/gitdm/group-map-individuals 
> b/contrib/gitdm/group-map-individuals
> index 301071b98b..624e27fc83 100644
> --- a/contrib/gitdm/group-map-individuals
> +++ b/contrib/gitdm/group-map-individuals
> @@ -18,3 +18,4 @@ e.emanuelegiuse...@gmail.com
>  dirty.ice...@gmail.com
>  liq...@163.com
>  liq...@gmail.com
> +andrew.smir...@gmail.com
> --
> 2.20.1
>



Re: [Qemu-devel] [PATCH 0/5] Various i.MX7 fixes

2019-06-17 Thread Andrey Smirnov
On Mon, Apr 15, 2019 at 6:39 PM Andrey Smirnov  wrote:
>
> Everyone:
>
> I recently revisited my i.MX7 work and this series contains all of the
> fixes I had to make to get it to work with latest (5.1-rc1) Linux
> kernel again as well as fixes for genuine bugs that I somehow missed
> during original submission ("pci: designware" patches). Hopefully each
> patch is self-explanatory.
>
> Feedback is welcome!
>

Is there any changes necessary for this to go in?

Thanks,
Andrey Smirnov



Re: [Qemu-devel] Maintainers, please tell us how to boot your machines!

2019-04-15 Thread Andrey Smirnov
On Tue, Mar 12, 2019 at 10:36 AM Markus Armbruster  wrote:
>
> Dear board code maintainers,
>
> This is a (rather late) follow-up to the last QEMU summit.  Minutes[*]:
>
>  * Deprecating unmaintained features (devices, targets, backends) in QEMU
>
>QEMU has a mechanism to deprecate features but there remains a lot of
>old unmaintained code.  Refactoring is hindered by untested legacy
>code, so there is a desire to deprecate unmaintained features more
>often.
>
>[...]
>
>We should require at least a minimal test for each board; if nobody
>cares enough to come up with one, that board should be deprecated.
>
>[...]
>
>Also see the qemu-devel discussion about deprecating code:
>https://lists.nongnu.org/archive/html/qemu-devel/2018-10/msg05828.html.
>
> That's a link to "Minutes of KVM Forum BoF on deprecating stuff".
> Quote:
>
>  * One obvious class of candidates for removal is machines we don't know
>how to boot, or can't boot, say because we lack required firmware
>and/or OS.
>
>Of course, "can boot" should be an automated test.  As a first step
>towards that, we should at least document how to boot each machine.
>We're going to ask machine maintainers to do that.
>
> Let's get going on this.
>
> I gathered the machine types, mapped them to source files, which I fed
> to get_maintainer.pl.  Results are appended.  If you're cc'ed,
> MAINTAINERS fingers you for at least one machine type's source file.
> Please tell us for all of them how to to a "meaningful" boot test.
>
> For now, what's "meaningful" is entirely up to you.  Booting Linux
> certainly is.
>
> Make sure to include a complete QEMU command line.  If your QEMU command
> line requires resources beyond the QEMU source tree and what we build
> from it, please detail them, and provide download URLs as far as
> possible.
>
> Goals for this exercise:
>
> * Gather information we need to cover more machines in our automated
>   testing.
>
>   Related work:
>   [PATCH v4 00/19] Acceptance Tests: target architecture support
>   Message-Id: <20190312121150.8638-1-cr...@redhat.com>
>   https://lists.gnu.org/archive/html/qemu-devel/2019-03/msg03881.html
>
> * Maybe identify a few machines we don't know how to boot anymore.
>
> Thanks in advance for your help!
>
>
>
> Machines with at least one maintainer:
>
>
> = hw/arm/mcimx7d-sabre.c =
> Peter Maydell  (odd fixer:MCIMX7D SABRE / i...)
> Andrey Smirnov  (reviewer:MCIMX7D SABRE / i...)
> qemu-...@nongnu.org (open list:MCIMX7D SABRE / i...)
>

Sorry I am late to this party. I haven't used i.MX7 emulation in a
while and things didn't go smoothly out of the box, so I had to create
a number of fixes (submitted to the ML).

I use Linux kernel built using Buildroot for validation. Buildroot
should have a default i.MX7 Sabred SD configuration and that should
probably work. I usually change mine slightly to use compiled-in
rootfs to simplify storage setup.

In case this is helpful here's a number of commands I use to start my
test cases:

* PCIe (e1000 ethernet attached), USB (usb stick attached), SD:
arm-softmmu/qemu-system-arm -smp 2 -m 1024 -machine mcimx7d-sabre
-nographic -serial mon:stdio -kernel  -dtb  -device e1000e,bus="dw-pcie",netdev=lan0 -netdev
tap,id=lan0,ifname=tap0,script=no,downscript=no -append
"console=ttymxc0,115200 noinitrd" -usb -drive
if=none,id=stick,file=,format=raw -device
usb-storage,bus=usb-bus.0,drive=stick -drive
id=sd1,if=sd,format=file,file= -drive
id=sd2,if=sd,format=file,file= -driv
eid=sd3,if=sd,format=file,file=

* EHCI USB attached via PCIe with legacy interrupts, Ethernet
connected to built-in controller:
arm-softmmu/qemu-system-arm -smp 2 -m 1024 -machine mcimx7d-sabre
-nographic -serial mon:stdio -kernel  -dtb  -device usb-ehci,id=ehci,bus="dw-pcie" -net
nic,model=imx.fec,netdev=lan0 -netdev
tap,id=lan0,ifname=tap0,script=no,downscript=no -append
"console=ttymxc0,115200 noinitrd pci=nomsi" -usb -drive
if=none,id=stick,file=,format=raw

Also, I don't think anyone would try to do this, but just as a
warning, building QEMU with --enable-tcg-interpreter doesn't really
work that well (/init gets SIGKILLed every time), so I'd recommend
avoiding using that option.

Hopefully this is enough info, but if not, feel free to ask me more questions.

Thanks,
Andrey Smirnov



[Qemu-devel] [PATCH 4/5] pci: designware: Update MSI mapping when MSI address changes

2019-04-15 Thread Andrey Smirnov
MSI mapping needs to be update when MSI address changes, so add the
code to do so.

Signed-off-by: Andrey Smirnov 
Cc: Peter Maydell 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
---
 hw/pci-host/designware.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index 6affe823c0..e80facc4a0 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -289,11 +289,13 @@ static void designware_pcie_root_config_write(PCIDevice 
*d, uint32_t address,
 case DESIGNWARE_PCIE_MSI_ADDR_LO:
 root->msi.base &= 0xULL;
 root->msi.base |= val;
+designware_pcie_root_update_msi_mapping(root);
 break;
 
 case DESIGNWARE_PCIE_MSI_ADDR_HI:
 root->msi.base &= 0xULL;
 root->msi.base |= (uint64_t)val << 32;
+designware_pcie_root_update_msi_mapping(root);
 break;
 
 case DESIGNWARE_PCIE_MSI_INTR0_ENABLE:
-- 
2.20.1




[Qemu-devel] [PATCH 3/5] pci: designware: Update MSI mapping unconditionally

2019-04-15 Thread Andrey Smirnov
Expression to calculate update_msi_mapping in code handling writes to
DESIGNWARE_PCIE_MSI_INTR0_ENABLE is missing an ! operator and should
be:

!!root->msi.intr[0].enable ^ !!val;

so that MSI mapping is updated when enabled transitions from either
"none" -> "any" or "any" -> "none". Since that register shouldn't be
written to very often, change the code to update MSI mapping
unconditionally instead of trying to fix the update_msi_mapping logic.

Signed-off-by: Andrey Smirnov 
Cc: Peter Maydell 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
---
 hw/pci-host/designware.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index 29ea313798..6affe823c0 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -296,16 +296,10 @@ static void designware_pcie_root_config_write(PCIDevice 
*d, uint32_t address,
 root->msi.base |= (uint64_t)val << 32;
 break;
 
-case DESIGNWARE_PCIE_MSI_INTR0_ENABLE: {
-const bool update_msi_mapping = !root->msi.intr[0].enable ^ !!val;
-
+case DESIGNWARE_PCIE_MSI_INTR0_ENABLE:
 root->msi.intr[0].enable = val;
-
-if (update_msi_mapping) {
-designware_pcie_root_update_msi_mapping(root);
-}
+designware_pcie_root_update_msi_mapping(root);
 break;
-}
 
 case DESIGNWARE_PCIE_MSI_INTR0_MASK:
 root->msi.intr[0].mask = val;
-- 
2.20.1




[Qemu-devel] [PATCH 2/5] i.mx7d: Add no-op/unimplemented PCIE PHY IP block

2019-04-15 Thread Andrey Smirnov
Add no-op/unimplemented PCIE PHY IP block. Needed by new kernels to
use PCIE.

Signed-off-by: Andrey Smirnov 
Cc: Peter Maydell 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
---
 include/hw/arm/fsl-imx7.h | 3 +++
 hw/arm/fsl-imx7.c | 5 +
 2 files changed, 8 insertions(+)

diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index aae4f860fc..3efa697adc 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -125,6 +125,9 @@ enum FslIMX7MemoryMap {
 FSL_IMX7_ADC2_ADDR= 0x3062,
 FSL_IMX7_ADCn_SIZE= 0x1000,
 
+FSL_IMX7_PCIE_PHY_ADDR= 0x306D,
+FSL_IMX7_PCIE_PHY_SIZE= 0x1,
+
 FSL_IMX7_GPC_ADDR = 0x303A,
 
 FSL_IMX7_I2C1_ADDR= 0x30A2,
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 1abfa5910c..813fb55ca9 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -532,6 +532,11 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
  */
 create_unimplemented_device("dma-apbh", FSL_IMX7_DMA_APBH_ADDR,
 FSL_IMX7_DMA_APBH_SIZE);
+/*
+ * PCIe PHY
+ */
+create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
+FSL_IMX7_PCIE_PHY_SIZE);
 }
 
 static void fsl_imx7_class_init(ObjectClass *oc, void *data)
-- 
2.20.1




[Qemu-devel] [PATCH 1/5] i.mx7d: Add no-op/unimplemented APBH DMA module

2019-04-15 Thread Andrey Smirnov
Instantiate no-op APBH DMA module. Needed to boot latest Linux kernel.

Signed-off-by: Andrey Smirnov 
Cc: Peter Maydell 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
---
 include/hw/arm/fsl-imx7.h | 3 +++
 hw/arm/fsl-imx7.c | 6 ++
 2 files changed, 9 insertions(+)

diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index d848262bfd..aae4f860fc 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -179,6 +179,9 @@ enum FslIMX7MemoryMap {
 FSL_IMX7_PCIE_REG_SIZE= 16 * 1024,
 
 FSL_IMX7_GPR_ADDR = 0x3034,
+
+FSL_IMX7_DMA_APBH_ADDR= 0x3300,
+FSL_IMX7_DMA_APBH_SIZE= 0x2000,
 };
 
 enum FslIMX7IRQs {
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
index 7663ad6861..1abfa5910c 100644
--- a/hw/arm/fsl-imx7.c
+++ b/hw/arm/fsl-imx7.c
@@ -526,6 +526,12 @@ static void fsl_imx7_realize(DeviceState *dev, Error 
**errp)
  */
 create_unimplemented_device("lcdif", FSL_IMX7_LCDIF_ADDR,
 FSL_IMX7_LCDIF_SIZE);
+
+/*
+ * DMA APBH
+ */
+create_unimplemented_device("dma-apbh", FSL_IMX7_DMA_APBH_ADDR,
+FSL_IMX7_DMA_APBH_SIZE);
 }
 
 static void fsl_imx7_class_init(ObjectClass *oc, void *data)
-- 
2.20.1




[Qemu-devel] [PATCH 5/5] i.mx7d: pci: Update PCI IRQ mapping to match HW

2019-04-15 Thread Andrey Smirnov
Datasheet for i.MX7 is incorrect and i.MX7's PCI IRQ mapping matches
that of i.MX6:

* INTD/MSI122
* INTC123
* INTB124
* INTA125

Fix all of the relevant code to reflect that fact. Needed by latest
Linux kernels.

Signed-off-by: Andrey Smirnov 
Cc: Peter Maydell 
Cc: Michael S. Tsirkin 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
---
 include/hw/arm/fsl-imx7.h | 8 
 hw/pci-host/designware.c  | 6 --
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
index 3efa697adc..9750003a4f 100644
--- a/include/hw/arm/fsl-imx7.h
+++ b/include/hw/arm/fsl-imx7.h
@@ -213,10 +213,10 @@ enum FslIMX7IRQs {
 FSL_IMX7_USB2_IRQ = 42,
 FSL_IMX7_USB3_IRQ = 40,
 
-FSL_IMX7_PCI_INTA_IRQ = 122,
-FSL_IMX7_PCI_INTB_IRQ = 123,
-FSL_IMX7_PCI_INTC_IRQ = 124,
-FSL_IMX7_PCI_INTD_IRQ = 125,
+FSL_IMX7_PCI_INTA_IRQ = 125,
+FSL_IMX7_PCI_INTB_IRQ = 124,
+FSL_IMX7_PCI_INTC_IRQ = 123,
+FSL_IMX7_PCI_INTD_IRQ = 122,
 
 FSL_IMX7_UART7_IRQ= 126,
 
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index e80facc4a0..f4c58b25c1 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -50,6 +50,8 @@
 #define DESIGNWARE_PCIE_ATU_DEVFN(x)   (((x) >> 16) & 0xff)
 #define DESIGNWARE_PCIE_ATU_UPPER_TARGET   0x91C
 
+#define DESIGNWARE_PCIE_IRQ_MSI3
+
 static DesignwarePCIEHost *
 designware_pcie_root_to_host(DesignwarePCIERoot *root)
 {
@@ -66,7 +68,7 @@ static void designware_pcie_root_msi_write(void *opaque, 
hwaddr addr,
 root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
 
 if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
-qemu_set_irq(host->pci.irqs[0], 1);
+qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 1);
 }
 }
 
@@ -310,7 +312,7 @@ static void designware_pcie_root_config_write(PCIDevice *d, 
uint32_t address,
 case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
 root->msi.intr[0].status ^= val;
 if (!root->msi.intr[0].status) {
-qemu_set_irq(host->pci.irqs[0], 0);
+qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 0);
 }
 break;
 
-- 
2.20.1




[Qemu-devel] [PATCH 0/5] Various i.MX7 fixes

2019-04-15 Thread Andrey Smirnov
Everyone:

I recently revisited my i.MX7 work and this series contains all of the
fixes I had to make to get it to work with latest (5.1-rc1) Linux
kernel again as well as fixes for genuine bugs that I somehow missed
during original submission ("pci: designware" patches). Hopefully each
patch is self-explanatory.

Feedback is welcome!

Thanks,
Andrey Smirnov

Andrey Smirnov (5):
  i.mx7d: Add no-op/unimplemented APBH DMA module
  i.mx7d: Add no-op/unimplemented PCIE PHY IP block
  pci: designware: Update MSI mapping unconditionally
  pci: designware: Update MSI mapping when MSI address changes
  i.mx7d: pci: Update PCI IRQ mapping to match HW

 include/hw/arm/fsl-imx7.h | 14 ++
 hw/arm/fsl-imx7.c | 11 +++
 hw/pci-host/designware.c  | 18 --
 3 files changed, 29 insertions(+), 14 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCH] hw/arm: Allow manually specified /psci node

2018-04-02 Thread Andrey Smirnov
Change the code to avoid exiting QEMU if user provided DTB contains
manually specified /psci node and skip any /psci related fixups
instead.

Fixes: 4cbca7d9b4 ("hw/arm: Move virt's PSCI DT fixup code to
arm/boot.c")

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Marc Zyngier <marc.zyng...@arm.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---

Mark:

Sorry about the inconvenience, here's the fix (hopefully) to the
prolem you reported in [1]. Let me know if skipping all PSCI related
DTB fixup if /psic node is present is not the behaviour you had in
mind for your suggested fix.

Thanks,
Andrey Smirnov

[1] http://lists.gnu.org/archive/html/qemu-devel/2018-03/msg06914.html

 hw/arm/boot.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 6d0c92ab88..d9f9375cdb 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -422,6 +422,7 @@ static void fdt_add_psci_node(void *fdt)
 ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
 const char *psci_method;
 int64_t psci_conduit;
+int rc;
 
 psci_conduit = object_property_get_int(OBJECT(armcpu),
"psci-conduit",
@@ -439,6 +440,15 @@ static void fdt_add_psci_node(void *fdt)
 g_assert_not_reached();
 }
 
+/*
+ * If /psci node is present in provided DTB, assume that no fixup
+ * is necessary and all PSCI configuration should be taken as-is
+ */
+rc = fdt_path_offset(fdt, "/psci");
+if (rc >= 0) {
+return;
+}
+
 qemu_fdt_add_subnode(fdt, "/psci");
 if (armcpu->psci_version == 2) {
 const char comp[] = "arm,psci-0.2\0arm,psci";
-- 
2.14.3




[Qemu-devel] [PATCH 2/2] char: i.MX: Add support for "TX complete" interrupt

2018-03-15 Thread Andrey Smirnov
Add support for "TX complete"/TXDC interrupt generate by real HW since
it is needed to support guests other than Linux.

Based on the patch by Bill Paul as found here:
https://bugs.launchpad.net/qemu/+bug/1753314

Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: Bill Paul <wp...@windriver.com>
Cc: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---

Bill:

I only tested this with i.MX7/Linux guest combo and am hoping you can
take this and previous patch and give it a try on your VxWorks setup.

Peter:

Bill is the author of original code, so I am not sure how to handle
Signed-off-by from him. I'd like to add it to this patch, but since
his original submission to launchpad didn't have one it is currently
omitted.

 include/hw/char/imx_serial.h |  3 +++
 hw/char/imx_serial.c | 20 +---
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
index baeec3183f..5b99cee7cf 100644
--- a/include/hw/char/imx_serial.h
+++ b/include/hw/char/imx_serial.h
@@ -67,6 +67,8 @@
 #define UCR2_RXEN   (1<<1)/* Receiver enable */
 #define UCR2_SRST   (1<<0)/* Reset complete */
 
+#define UCR4_TCEN   BIT(3)/* TX complete interrupt enable */
+
 #define UTS1_TXEMPTY(1<<6)
 #define UTS1_RXEMPTY(1<<5)
 #define UTS1_TXFULL (1<<4)
@@ -95,6 +97,7 @@ typedef struct IMXSerialState {
 uint32_t ubmr;
 uint32_t ubrc;
 uint32_t ucr3;
+uint32_t ucr4;
 
 qemu_irq irq;
 CharBackend chr;
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index d1e8586280..1e5540472b 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -37,8 +37,8 @@
 
 static const VMStateDescription vmstate_imx_serial = {
 .name = TYPE_IMX_SERIAL,
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .fields = (VMStateField[]) {
 VMSTATE_INT32(readbuff, IMXSerialState),
 VMSTATE_UINT32(usr1, IMXSerialState),
@@ -50,6 +50,7 @@ static const VMStateDescription vmstate_imx_serial = {
 VMSTATE_UINT32(ubmr, IMXSerialState),
 VMSTATE_UINT32(ubrc, IMXSerialState),
 VMSTATE_UINT32(ucr3, IMXSerialState),
+VMSTATE_UINT32(ucr4, IMXSerialState),
 VMSTATE_END_OF_LIST()
 },
 };
@@ -71,6 +72,11 @@ static void imx_update(IMXSerialState *s)
  * unfortunately.
  */
 mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
+/*
+ * TCEN and TXDC are both bit 3
+ */
+mask |= s->ucr4 & UCR4_TCEN;
+
 usr2 = s->usr2 & mask;
 
 qemu_set_irq(s->irq, usr1 || usr2);
@@ -163,6 +169,8 @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
 return s->ucr3;
 
 case 0x23: /* UCR4 */
+return s->ucr4;
+
 case 0x29: /* BRM Incremental */
 return 0x0; /* TODO */
 
@@ -191,8 +199,10 @@ static void imx_serial_write(void *opaque, hwaddr offset,
  * qemu_chr_fe_write and background I/O callbacks */
 qemu_chr_fe_write_all(>chr, , 1);
 s->usr1 &= ~USR1_TRDY;
+s->usr2 &= ~USR2_TXDC;
 imx_update(s);
 s->usr1 |= USR1_TRDY;
+s->usr2 |= USR2_TXDC;
 imx_update(s);
 }
 break;
@@ -265,8 +275,12 @@ static void imx_serial_write(void *opaque, hwaddr offset,
 s->ucr3 = value & 0x;
 break;
 
-case 0x2d: /* UTS1 */
 case 0x23: /* UCR4 */
+s->ucr4 = value & 0x;
+imx_update(s);
+break;
+
+case 0x2d: /* UTS1 */
 qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
   HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
 /* TODO */
-- 
2.14.3




[Qemu-devel] [PATCH 1/2] char: i.MX: Simplify imx_update()

2018-03-15 Thread Andrey Smirnov
Code of imx_update() is slightly confusing since the "flags" variable
doesn't really corespond to anything in real hardware and server as a
kitchensink accumulating events normally reported via USR1 and USR2
registers.

Change the code to explicitly evaluate state of interrupts reported
via USR1 and USR2 against corresponding masking bits and use the to
detemine if IRQ line should be asserted or not.

NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
reasons:

1. Emulation code implements a single character FIFO, so this flag
   will always be set since characters are trasmitted as a part of
   the code emulating "push" into the FIFO

2. imx_update() is really just a function doing ORing and maksing
   of reported events, so checking for UTS1_TXEMPTY should happen,
   if it's ever really needed should probably happen outside of
   it.

Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: Bill Paul <wp...@windriver.com>
Cc: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/char/imx_serial.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 70405ccf8b..d1e8586280 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -56,16 +56,24 @@ static const VMStateDescription vmstate_imx_serial = {
 
 static void imx_update(IMXSerialState *s)
 {
-uint32_t flags;
+uint32_t usr1;
+uint32_t usr2;
+uint32_t mask;
 
-flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
-if (s->ucr1 & UCR1_TXMPTYEN) {
-flags |= (s->uts1 & UTS1_TXEMPTY);
-} else {
-flags &= ~USR1_TRDY;
-}
+/*
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
+ * UCR1, so we can get away with something as simple as the
+ * following:
+ */
+usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
+/*
+ * Bits that we want in USR2 are not as conveniently laid out,
+ * unfortunately.
+ */
+mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
+usr2 = s->usr2 & mask;
 
-qemu_set_irq(s->irq, !!flags);
+qemu_set_irq(s->irq, usr1 || usr2);
 }
 
 static void imx_serial_reset(IMXSerialState *s)
-- 
2.14.3




Re: [Qemu-devel] [RESEND PATCH v7 0/3] Initial i.MX7 support

2018-03-05 Thread Andrey Smirnov
On Mon, Mar 5, 2018 at 7:31 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:
> On 5 March 2018 at 06:12, Andrey Smirnov <andrew.smir...@gmail.com> wrote:
>> RESEND due to botched original v7 submission (patch 1/3 broken)
>>
>> Hi everyone,
>>
>> This v7 of the patch series containing the work that I've done in
>> order to enable support for i.MX7 emulation in QEMU.
>
> Thanks; applied to target-arm.next.
>
> By the way there were a couple of i.MX bug reports this weekend:
> https://bugs.launchpad.net/qemu/+bug/1753314  (about the UART)

Sure, might not be able to look at it immediately but I'll give it a
spin by the end of this week.

> https://bugs.launchpad.net/qemu/+bug/1753309  (about ethernet)
>

Peter:

Ha! This is a rather amusing coincidence since I was just talking
about this exact bug with Guenter Roeck (added to this thread), who
was going to submit a patch to fix it.

Guenter:

Sorry for just randomly pulling you into this seemingly random
discussion, but I though this additional context would be helpful to
you.

Thanks,
Andrey Smirnov



[Qemu-devel] [RESEND PATCH v7 1/3] pci: Add support for Designware IP block

2018-03-04 Thread Andrey Smirnov
Add code needed to get a functional PCI subsytem when using in
conjunction with upstream Linux guest (4.13+). Tested to work against
"e1000e" (network adapter, using MSI interrupts) as well as
"usb-ehci" (USB controller, using legacy PCI interrupts).

Based on "i.MX6 Applications Processor Reference Manual" (Document
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak  |   2 +
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/pci-host/designware.c | 754 +++
 hw/pci-host/Makefile.objs|   2 +
 5 files changed, 862 insertions(+)
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/pci-host/designware.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d724106bd3..5540ea5e7e 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -140,3 +140,5 @@ CONFIG_GPIO_KEY=y
 CONFIG_MSF2=y
 CONFIG_FW_CFG_DMA=y
 CONFIG_XILINX_AXI=y
+CONFIG_PCI_DESIGNWARE=y
+
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
new file mode 100644
index 00..a4f2c0695b
--- /dev/null
+++ b/include/hw/pci-host/designware.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Designware PCIe IP block emulation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DESIGNWARE_H
+#define DESIGNWARE_H
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pci_bridge.h"
+
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
+#define DESIGNWARE_PCIE_HOST(obj) \
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
+
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
+#define DESIGNWARE_PCIE_ROOT(obj) \
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
+
+struct DesignwarePCIERoot;
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
+
+typedef struct DesignwarePCIEViewport {
+DesignwarePCIERoot *root;
+
+MemoryRegion cfg;
+MemoryRegion mem;
+
+uint64_t base;
+uint64_t target;
+uint32_t limit;
+uint32_t cr[2];
+
+bool inbound;
+} DesignwarePCIEViewport;
+
+typedef struct DesignwarePCIEMSIBank {
+uint32_t enable;
+uint32_t mask;
+uint32_t status;
+} DesignwarePCIEMSIBank;
+
+typedef struct DesignwarePCIEMSI {
+uint64_t base;
+MemoryRegion iomem;
+
+#define DESIGNWARE_PCIE_NUM_MSI_BANKS1
+
+DesignwarePCIEMSIBank intr[DESIGNWARE_PCIE_NUM_MSI_BANKS];
+} DesignwarePCIEMSI;
+
+struct DesignwarePCIERoot {
+PCIBridge parent_obj;
+
+uint32_t atu_viewport;
+
+#define DESIGNWARE_PCIE_VIEWPORT_OUTBOUND0
+#define DESIGNWARE_PCIE_VIEWPORT_INBOUND 1
+#define DESIGNWARE_PCIE_NUM_VIEWPORTS4
+
+DesignwarePCIEViewport viewports[2][DESIGNWARE_PCIE_NUM_VIEWPORTS];
+DesignwarePCIEMSI msi;
+};
+
+typedef struct DesignwarePCIEHost {
+PCIHostState parent_obj;
+
+DesignwarePCIERoot root;
+
+struct {
+AddressSpace address_space;
+MemoryRegion address_space_root;
+
+MemoryRegion memory;
+MemoryRegion io;
+
+qemu_irq irqs[4];
+} pci;
+
+MemoryRegion mmio;
+} DesignwarePCIEHost;
+
+#endif  /* DESIGNWARE_H */
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 1dbf53627c..63acc722a9 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -269,4 +269,6 @@
 #define PCI_VENDOR_ID_VMWARE 0x15ad
 #define PCI_DEVICE_ID_VMWARE_PVRDMA  0x0820
 
+#define PCI_VENDOR_ID_SYNOPSYS   0x16C3
+
 #endif
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c

[Qemu-devel] [RESEND PATCH v7 0/3] Initial i.MX7 support

2018-03-04 Thread Andrey Smirnov
RESEND due to botched original v7 submission (patch 1/3 broken)

Hi everyone,

This v7 of the patch series containing the work that I've done in
order to enable support for i.MX7 emulation in QEMU.

As the one before last commit in the series states the supported i.MX7
features are:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller
* 3 USB controllers
* 1 LCD controller
* 1 ARMv7 DAP IP block

Feedback is welcome!

Changes since [v6]:

- Removed reference to "is_express"

- All endiannes in Designware PCI implementation is now specified
  as little-endian

- Patchset rebase on latest master
  (136c67e07869227b21b3f627316e03679ce7b738)


Changes since [v5]:

- Rebase patchest on top of latest QEMU master, so now the
  patchset is down to three patches

- Reverted the change to use pci_data_* functions becuase the
  patch supporting this change was causing trouble

- Fixed endiannes of MSI and configuration space accessors to be
  LITTLE_ENDIAN

Changes since [v4]:

- Rebase patchest on top of latest QEMU master

- Reworked PCIE emulation code to create MemoryRegions
  only once

- Fixed incorrect usages of PCI instead of PCIE

- Fixed device class reported by PCIE bridge

- Added patch to make pci_data_read() and pci_data_write() usable
  for PCIE devices as well

- Converted PCIE code to use pci_data_read() and pci_data_write()

- Added VMStateDescription code for PCIE

- Collected Reviewed-by tag from Philippe

Changes since [v3]:

- Changes to FEC were split into a separate set and merged to master

- Patchest is rebased on latest master

- Converted to use PSCI DT fixup code that is shared with virt
  platform (now relocated to live in arm/boot.c)

- Large number of dummy block were converted to use
  create_unimplemented_device() as opposed to its own dedicated
  type

- Incorporated varios small feedback items

- Collected Reviewed-by tags from Peter

Changes since [v2]:

- Added stubs for more blocks that were causing memory
  transactions when booting Linux guest as were revealed by
  additional testing of the patchest

- Added proper USB emulation code, so now it should be possible to
  emulated guest's USB bus

Changes since [v1]:

- Patchset no longer relies on "ignore_memory_transaction_failures = false"
  for its functionality

- As a consequnce of implementing the above a number of patches
  implementing dummy IP block emulation as well as PCIe emulation
  patches that I alluded to in [v1] are now included in this patch
  series

- "has_el3" property is no longer being set to "false" as a part
  of intialization of A7 CPU. I couldn't reproduce the issues that
  I thought I was having, so I just dropped that code.

- A number of smaller feedback items from Peter and other has been
  incorporated into the patches.


Thanks,
Andrey Smirnov

[v6] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg03587.html
[v5] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg01558.html
[v4] https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg03264.html
[v3] https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg04236.html
[v2] https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05516.html
[v1] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg04770.html

Andrey Smirnov (3):
  pci: Add support for Designware IP block
  i.MX: Add i.MX7 SOC implementation.
  Implement support for i.MX7 Sabre board

 default-configs/arm-softmmu.mak  |   3 +
 include/hw/arm/fsl-imx7.h| 222 
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/arm/fsl-imx7.c| 580 ++
 hw/arm/mcimx7d-sabre.c   |  90 +
 hw/pci-host/designware.c | 754 +++
 hw/arm/Makefile.objs |   3 +
 hw/pci-host/Makefile.objs|   2 +
 9 files changed, 1758 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/arm/fsl-imx7.c
 create mode 100644 hw/arm/mcimx7d-sabre.c
 create mode 100644 hw/pci-host/designware.c

-- 
2.14.3




[Qemu-devel] [RESEND PATCH v7 2/3] i.MX: Add i.MX7 SOC implementation.

2018-03-04 Thread Andrey Smirnov
The following interfaces are partially or fully emulated:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller

Tested to boot and work with upstream Linux (4.13+) guest.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak |   1 +
 include/hw/arm/fsl-imx7.h   | 222 +++
 hw/arm/fsl-imx7.c   | 580 
 hw/arm/Makefile.objs|   2 +
 4 files changed, 805 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 hw/arm/fsl-imx7.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 5540ea5e7e..7665a02fb2 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -126,6 +126,7 @@ CONFIG_ALLWINNER_A10=y
 CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
+CONFIG_FSL_IMX7=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
new file mode 100644
index 00..d848262bfd
--- /dev/null
+++ b/include/hw/arm/fsl-imx7.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 SoC definitions
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef FSL_IMX7_H
+#define FSL_IMX7_H
+
+#include "hw/arm/arm.h"
+#include "hw/cpu/a15mpcore.h"
+#include "hw/intc/imx_gpcv2.h"
+#include "hw/misc/imx7_ccm.h"
+#include "hw/misc/imx7_snvs.h"
+#include "hw/misc/imx7_gpr.h"
+#include "hw/misc/imx6_src.h"
+#include "hw/misc/imx2_wdt.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/char/imx_serial.h"
+#include "hw/timer/imx_gpt.h"
+#include "hw/timer/imx_epit.h"
+#include "hw/i2c/imx_i2c.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/sd/sdhci.h"
+#include "hw/ssi/imx_spi.h"
+#include "hw/net/imx_fec.h"
+#include "hw/pci-host/designware.h"
+#include "hw/usb/chipidea.h"
+#include "exec/memory.h"
+#include "cpu.h"
+
+#define TYPE_FSL_IMX7 "fsl,imx7"
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
+
+enum FslIMX7Configuration {
+FSL_IMX7_NUM_CPUS = 2,
+FSL_IMX7_NUM_UARTS= 7,
+FSL_IMX7_NUM_ETHS = 2,
+FSL_IMX7_ETH_NUM_TX_RINGS = 3,
+FSL_IMX7_NUM_USDHCS   = 3,
+FSL_IMX7_NUM_WDTS = 4,
+FSL_IMX7_NUM_GPTS = 4,
+FSL_IMX7_NUM_IOMUXCS  = 2,
+FSL_IMX7_NUM_GPIOS= 7,
+FSL_IMX7_NUM_I2CS = 4,
+FSL_IMX7_NUM_ECSPIS   = 4,
+FSL_IMX7_NUM_USBS = 3,
+FSL_IMX7_NUM_ADCS = 2,
+};
+
+typedef struct FslIMX7State {
+/*< private >*/
+DeviceStateparent_obj;
+
+/*< public >*/
+ARMCPU cpu[FSL_IMX7_NUM_CPUS];
+A15MPPrivState a7mpcore;
+IMXGPTStategpt[FSL_IMX7_NUM_GPTS];
+IMXGPIOState   gpio[FSL_IMX7_NUM_GPIOS];
+IMX7CCMState   ccm;
+IMX7AnalogStateanalog;
+IMX7SNVSState  snvs;
+IMXGPCv2State  gpcv2;
+IMXSPIStatespi[FSL_IMX7_NUM_ECSPIS];
+IMXI2CStatei2c[FSL_IMX7_NUM_I2CS];
+IMXSerialState uart[FSL_IMX7_NUM_UARTS];
+IMXFECStateeth[FSL_IMX7_NUM_ETHS];
+SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
+IMX2WdtState   wdt[FSL_IMX7_NUM_WDTS];
+IMX7GPRState   gpr;
+ChipideaState  usb[FSL_IMX7_NUM_USBS];
+DesignwarePCIEHost pcie;
+} FslIMX7State;
+
+enu

Re: [Qemu-devel] [PATCH v7 0/3] Initial i.MX7 support

2018-03-04 Thread Andrey Smirnov
On Sun, Mar 4, 2018 at 9:16 PM, Andrey Smirnov <andrew.smir...@gmail.com> wrote:
> Hi everyone,
>

Ugh, just realized that I was too hasty to call git "send-email" and
patch 1/3 in this submission is broken since I forgot to remove
"is_express" field. Please disregard this version of v7 and I'll
resend corrected one shortly.

Very sorry for the noise.

Thanks,
Andrey Smirnov



[Qemu-devel] [PATCH v7 1/3] pci: Add support for Designware IP block

2018-03-04 Thread Andrey Smirnov
Add code needed to get a functional PCI subsytem when using in
conjunction with upstream Linux guest (4.13+). Tested to work against
"e1000e" (network adapter, using MSI interrupts) as well as
"usb-ehci" (USB controller, using legacy PCI interrupts).

Based on "i.MX6 Applications Processor Reference Manual" (Document
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak  |   2 +
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/pci-host/designware.c | 755 +++
 hw/pci-host/Makefile.objs|   2 +
 5 files changed, 863 insertions(+)
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/pci-host/designware.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d724106bd3..5540ea5e7e 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -140,3 +140,5 @@ CONFIG_GPIO_KEY=y
 CONFIG_MSF2=y
 CONFIG_FW_CFG_DMA=y
 CONFIG_XILINX_AXI=y
+CONFIG_PCI_DESIGNWARE=y
+
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
new file mode 100644
index 00..a4f2c0695b
--- /dev/null
+++ b/include/hw/pci-host/designware.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Designware PCIe IP block emulation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DESIGNWARE_H
+#define DESIGNWARE_H
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pci_bridge.h"
+
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
+#define DESIGNWARE_PCIE_HOST(obj) \
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
+
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
+#define DESIGNWARE_PCIE_ROOT(obj) \
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
+
+struct DesignwarePCIERoot;
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
+
+typedef struct DesignwarePCIEViewport {
+DesignwarePCIERoot *root;
+
+MemoryRegion cfg;
+MemoryRegion mem;
+
+uint64_t base;
+uint64_t target;
+uint32_t limit;
+uint32_t cr[2];
+
+bool inbound;
+} DesignwarePCIEViewport;
+
+typedef struct DesignwarePCIEMSIBank {
+uint32_t enable;
+uint32_t mask;
+uint32_t status;
+} DesignwarePCIEMSIBank;
+
+typedef struct DesignwarePCIEMSI {
+uint64_t base;
+MemoryRegion iomem;
+
+#define DESIGNWARE_PCIE_NUM_MSI_BANKS1
+
+DesignwarePCIEMSIBank intr[DESIGNWARE_PCIE_NUM_MSI_BANKS];
+} DesignwarePCIEMSI;
+
+struct DesignwarePCIERoot {
+PCIBridge parent_obj;
+
+uint32_t atu_viewport;
+
+#define DESIGNWARE_PCIE_VIEWPORT_OUTBOUND0
+#define DESIGNWARE_PCIE_VIEWPORT_INBOUND 1
+#define DESIGNWARE_PCIE_NUM_VIEWPORTS4
+
+DesignwarePCIEViewport viewports[2][DESIGNWARE_PCIE_NUM_VIEWPORTS];
+DesignwarePCIEMSI msi;
+};
+
+typedef struct DesignwarePCIEHost {
+PCIHostState parent_obj;
+
+DesignwarePCIERoot root;
+
+struct {
+AddressSpace address_space;
+MemoryRegion address_space_root;
+
+MemoryRegion memory;
+MemoryRegion io;
+
+qemu_irq irqs[4];
+} pci;
+
+MemoryRegion mmio;
+} DesignwarePCIEHost;
+
+#endif  /* DESIGNWARE_H */
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 1dbf53627c..63acc722a9 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -269,4 +269,6 @@
 #define PCI_VENDOR_ID_VMWARE 0x15ad
 #define PCI_DEVICE_ID_VMWARE_PVRDMA  0x0820
 
+#define PCI_VENDOR_ID_SYNOPSYS   0x16C3
+
 #endif
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c

[Qemu-devel] [PATCH v7 2/3] i.MX: Add i.MX7 SOC implementation.

2018-03-04 Thread Andrey Smirnov
The following interfaces are partially or fully emulated:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller

Tested to boot and work with upstream Linux (4.13+) guest.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak |   1 +
 include/hw/arm/fsl-imx7.h   | 222 +++
 hw/arm/fsl-imx7.c   | 580 
 hw/arm/Makefile.objs|   2 +
 4 files changed, 805 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 hw/arm/fsl-imx7.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 5540ea5e7e..7665a02fb2 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -126,6 +126,7 @@ CONFIG_ALLWINNER_A10=y
 CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
+CONFIG_FSL_IMX7=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
new file mode 100644
index 00..d848262bfd
--- /dev/null
+++ b/include/hw/arm/fsl-imx7.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 SoC definitions
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef FSL_IMX7_H
+#define FSL_IMX7_H
+
+#include "hw/arm/arm.h"
+#include "hw/cpu/a15mpcore.h"
+#include "hw/intc/imx_gpcv2.h"
+#include "hw/misc/imx7_ccm.h"
+#include "hw/misc/imx7_snvs.h"
+#include "hw/misc/imx7_gpr.h"
+#include "hw/misc/imx6_src.h"
+#include "hw/misc/imx2_wdt.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/char/imx_serial.h"
+#include "hw/timer/imx_gpt.h"
+#include "hw/timer/imx_epit.h"
+#include "hw/i2c/imx_i2c.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/sd/sdhci.h"
+#include "hw/ssi/imx_spi.h"
+#include "hw/net/imx_fec.h"
+#include "hw/pci-host/designware.h"
+#include "hw/usb/chipidea.h"
+#include "exec/memory.h"
+#include "cpu.h"
+
+#define TYPE_FSL_IMX7 "fsl,imx7"
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
+
+enum FslIMX7Configuration {
+FSL_IMX7_NUM_CPUS = 2,
+FSL_IMX7_NUM_UARTS= 7,
+FSL_IMX7_NUM_ETHS = 2,
+FSL_IMX7_ETH_NUM_TX_RINGS = 3,
+FSL_IMX7_NUM_USDHCS   = 3,
+FSL_IMX7_NUM_WDTS = 4,
+FSL_IMX7_NUM_GPTS = 4,
+FSL_IMX7_NUM_IOMUXCS  = 2,
+FSL_IMX7_NUM_GPIOS= 7,
+FSL_IMX7_NUM_I2CS = 4,
+FSL_IMX7_NUM_ECSPIS   = 4,
+FSL_IMX7_NUM_USBS = 3,
+FSL_IMX7_NUM_ADCS = 2,
+};
+
+typedef struct FslIMX7State {
+/*< private >*/
+DeviceStateparent_obj;
+
+/*< public >*/
+ARMCPU cpu[FSL_IMX7_NUM_CPUS];
+A15MPPrivState a7mpcore;
+IMXGPTStategpt[FSL_IMX7_NUM_GPTS];
+IMXGPIOState   gpio[FSL_IMX7_NUM_GPIOS];
+IMX7CCMState   ccm;
+IMX7AnalogStateanalog;
+IMX7SNVSState  snvs;
+IMXGPCv2State  gpcv2;
+IMXSPIStatespi[FSL_IMX7_NUM_ECSPIS];
+IMXI2CStatei2c[FSL_IMX7_NUM_I2CS];
+IMXSerialState uart[FSL_IMX7_NUM_UARTS];
+IMXFECStateeth[FSL_IMX7_NUM_ETHS];
+SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
+IMX2WdtState   wdt[FSL_IMX7_NUM_WDTS];
+IMX7GPRState   gpr;
+ChipideaState  usb[FSL_IMX7_NUM_USBS];
+DesignwarePCIEHost pcie;
+} FslIMX7State;
+
+enu

[Qemu-devel] [PATCH v7 0/3] Initial i.MX7 support

2018-03-04 Thread Andrey Smirnov
Hi everyone,

This v7 of the patch series containing the work that I've done in
order to enable support for i.MX7 emulation in QEMU.

As the one before last commit in the series states the supported i.MX7
features are:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller
* 3 USB controllers
* 1 LCD controller
* 1 ARMv7 DAP IP block

Feedback is welcome!

Changes since [v6]:

- All endiannes in Designware PCI implementation is now specified
  as little-endian

Changes since [v5]:

- Rebase patchest on top of latest QEMU master, so now the
  patchset is down to three patches

- Reverted the change to use pci_data_* functions becuase the
  patch supporting this change was causing trouble

- Fixed endiannes of MSI and configuration space accessors to be
  LITTLE_ENDIAN

Changes since [v4]:

- Rebase patchest on top of latest QEMU master

- Reworked PCIE emulation code to create MemoryRegions
  only once

- Fixed incorrect usages of PCI instead of PCIE

- Fixed device class reported by PCIE bridge

- Added patch to make pci_data_read() and pci_data_write() usable
  for PCIE devices as well

- Converted PCIE code to use pci_data_read() and pci_data_write()

- Added VMStateDescription code for PCIE

- Collected Reviewed-by tag from Philippe

Changes since [v3]:

- Changes to FEC were split into a separate set and merged to master

- Patchest is rebased on latest master

- Converted to use PSCI DT fixup code that is shared with virt
  platform (now relocated to live in arm/boot.c)

- Large number of dummy block were converted to use
  create_unimplemented_device() as opposed to its own dedicated
  type

- Incorporated varios small feedback items

- Collected Reviewed-by tags from Peter

Changes since [v2]:

- Added stubs for more blocks that were causing memory
  transactions when booting Linux guest as were revealed by
  additional testing of the patchest

- Added proper USB emulation code, so now it should be possible to
  emulated guest's USB bus

Changes since [v1]:

- Patchset no longer relies on "ignore_memory_transaction_failures = false"
  for its functionality

- As a consequnce of implementing the above a number of patches
  implementing dummy IP block emulation as well as PCIe emulation
  patches that I alluded to in [v1] are now included in this patch
  series

- "has_el3" property is no longer being set to "false" as a part
  of intialization of A7 CPU. I couldn't reproduce the issues that
  I thought I was having, so I just dropped that code.

- A number of smaller feedback items from Peter and other has been
  incorporated into the patches.


Thanks,
Andrey Smirnov

[v6] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg03587.html
[v5] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg01558.html
[v4] https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg03264.html
[v3] https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg04236.html
[v2] https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05516.html
[v1] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg04770.html

Andrey Smirnov (3):
  pci: Add support for Designware IP block
  i.MX: Add i.MX7 SOC implementation.
  Implement support for i.MX7 Sabre board

 default-configs/arm-softmmu.mak  |   3 +
 include/hw/arm/fsl-imx7.h| 222 
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/arm/fsl-imx7.c| 580 ++
 hw/arm/mcimx7d-sabre.c   |  90 +
 hw/pci-host/designware.c | 755 +++
 hw/arm/Makefile.objs |   3 +
 hw/pci-host/Makefile.objs|   2 +
 9 files changed, 1759 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/arm/fsl-imx7.c
 create mode 100644 hw/arm/mcimx7d-sabre.c
 create mode 100644 hw/pci-host/designware.c

-- 
2.14.3




Re: [Qemu-devel] [PATCH v6 1/3] pci: Add support for Designware IP block

2018-03-03 Thread Andrey Smirnov
On Sat, Mar 3, 2018 at 7:55 PM, Michael S. Tsirkin <m...@redhat.com> wrote:
> On Tue, Feb 13, 2018 at 02:47:24PM -0800, Andrey Smirnov wrote:
>> On Tue, Feb 13, 2018 at 2:15 PM, Michael S. Tsirkin <m...@redhat.com> wrote:
>> > On Tue, Feb 13, 2018 at 12:24:40PM -0800, Andrey Smirnov wrote:
>> >> On Tue, Feb 13, 2018 at 10:13 AM, Michael S. Tsirkin <m...@redhat.com> 
>> >> wrote:
>> >> > On Tue, Feb 13, 2018 at 09:07:10AM -0800, Andrey Smirnov wrote:
>> >> >> +static void designware_pcie_root_class_init(ObjectClass *klass, void 
>> >> >> *data)
>> >> >> +{
>> >> >> +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> >> >> +DeviceClass *dc = DEVICE_CLASS(klass);
>> >> >> +
>> >> >> +set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>> >> >> +
>> >> >> +k->vendor_id = PCI_VENDOR_ID_SYNOPSYS;
>> >> >> +k->device_id = 0xABCD;
>> >> >> +k->revision = 0;
>> >> >> +k->class_id = PCI_CLASS_BRIDGE_PCI;
>> >> >> +k->is_express = true;
>> >> >> +k->is_bridge = true;
>> >> >> +k->exit = pci_bridge_exitfn;
>> >> >> +k->realize = designware_pcie_root_realize;
>> >> >> +k->config_read = designware_pcie_root_config_read;
>> >> >> +k->config_write = designware_pcie_root_config_write;
>> >> >> +
>> >> >> +dc->reset = pci_bridge_reset;
>> >> >> +/*
>> >> >> + * PCI-facing part of the host bridge, not usable without the
>> >> >> + * host-facing part, which can't be device_add'ed, yet.
>> >> >> + */
>> >> >> +dc->user_creatable = false;
>> >> >> +dc->vmsd = _designware_pcie_root;
>> >> >> +}
>> >> >> +
>> >> >> +static uint64_t designware_pcie_host_mmio_read(void *opaque, hwaddr 
>> >> >> addr,
>> >> >> +   unsigned int size)
>> >> >> +{
>> >> >> +PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
>> >> >> +PCIDevice *device = pci_find_device(pci->bus, 0, 0);
>> >> >> +
>> >> >> +return pci_host_config_read_common(device,
>> >> >> +   addr,
>> >> >> +   pci_config_size(device),
>> >> >> +   size);
>> >> >> +}
>> >> >> +
>> >> >> +static void designware_pcie_host_mmio_write(void *opaque, hwaddr addr,
>> >> >> +uint64_t val, unsigned 
>> >> >> int size)
>> >> >> +{
>> >> >> +PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
>> >> >> +PCIDevice *device = pci_find_device(pci->bus, 0, 0);
>> >> >> +
>> >> >> +return pci_host_config_write_common(device,
>> >> >> +addr,
>> >> >> +pci_config_size(device),
>> >> >> +val, size);
>> >> >> +}
>> >> >> +
>> >> >> +static const MemoryRegionOps designware_pci_mmio_ops = {
>> >> >> +.read   = designware_pcie_host_mmio_read,
>> >> >> +.write  = designware_pcie_host_mmio_write,
>> >> >> +.endianness = DEVICE_NATIVE_ENDIAN,
>> >> >> +.impl = {
>> >> >> +/*
>> >> >> + * Our device would not work correctly if the guest was doing
>> >> >> + * unaligned access. This might not be a limitation on the 
>> >> >> real
>> >> >> + * device but in practice there is no reason for a guest to 
>> >> >> access
>> >> >> + * this device unaligned.
>> >> >> + */
>> >> >> +.min_access_size = 4,
>> >> >> +.max_access_size = 4,
>> >> >> +.unaligned = false,
>> >> >> +},
>> >> >> +};
>> >> >
>> >> >

Re: [Qemu-devel] [PATCH v6 1/3] pci: Add support for Designware IP block

2018-03-03 Thread Andrey Smirnov
On Tue, Feb 13, 2018 at 2:47 PM, Andrey Smirnov
<andrew.smir...@gmail.com> wrote:
> On Tue, Feb 13, 2018 at 2:15 PM, Michael S. Tsirkin <m...@redhat.com> wrote:
>> On Tue, Feb 13, 2018 at 12:24:40PM -0800, Andrey Smirnov wrote:
>>> On Tue, Feb 13, 2018 at 10:13 AM, Michael S. Tsirkin <m...@redhat.com> 
>>> wrote:
>>> > On Tue, Feb 13, 2018 at 09:07:10AM -0800, Andrey Smirnov wrote:
>>> >> +static void designware_pcie_root_class_init(ObjectClass *klass, void 
>>> >> *data)
>>> >> +{
>>> >> +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>>> >> +DeviceClass *dc = DEVICE_CLASS(klass);
>>> >> +
>>> >> +set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>>> >> +
>>> >> +k->vendor_id = PCI_VENDOR_ID_SYNOPSYS;
>>> >> +k->device_id = 0xABCD;
>>> >> +k->revision = 0;
>>> >> +k->class_id = PCI_CLASS_BRIDGE_PCI;
>>> >> +k->is_express = true;
>>> >> +k->is_bridge = true;
>>> >> +k->exit = pci_bridge_exitfn;
>>> >> +k->realize = designware_pcie_root_realize;
>>> >> +k->config_read = designware_pcie_root_config_read;
>>> >> +k->config_write = designware_pcie_root_config_write;
>>> >> +
>>> >> +dc->reset = pci_bridge_reset;
>>> >> +/*
>>> >> + * PCI-facing part of the host bridge, not usable without the
>>> >> + * host-facing part, which can't be device_add'ed, yet.
>>> >> + */
>>> >> +dc->user_creatable = false;
>>> >> +dc->vmsd = _designware_pcie_root;
>>> >> +}
>>> >> +
>>> >> +static uint64_t designware_pcie_host_mmio_read(void *opaque, hwaddr 
>>> >> addr,
>>> >> +   unsigned int size)
>>> >> +{
>>> >> +PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
>>> >> +PCIDevice *device = pci_find_device(pci->bus, 0, 0);
>>> >> +
>>> >> +return pci_host_config_read_common(device,
>>> >> +   addr,
>>> >> +   pci_config_size(device),
>>> >> +   size);
>>> >> +}
>>> >> +
>>> >> +static void designware_pcie_host_mmio_write(void *opaque, hwaddr addr,
>>> >> +uint64_t val, unsigned int 
>>> >> size)
>>> >> +{
>>> >> +PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
>>> >> +PCIDevice *device = pci_find_device(pci->bus, 0, 0);
>>> >> +
>>> >> +return pci_host_config_write_common(device,
>>> >> +addr,
>>> >> +pci_config_size(device),
>>> >> +val, size);
>>> >> +}
>>> >> +
>>> >> +static const MemoryRegionOps designware_pci_mmio_ops = {
>>> >> +.read   = designware_pcie_host_mmio_read,
>>> >> +.write  = designware_pcie_host_mmio_write,
>>> >> +.endianness = DEVICE_NATIVE_ENDIAN,
>>> >> +.impl = {
>>> >> +/*
>>> >> + * Our device would not work correctly if the guest was doing
>>> >> + * unaligned access. This might not be a limitation on the real
>>> >> + * device but in practice there is no reason for a guest to 
>>> >> access
>>> >> + * this device unaligned.
>>> >> + */
>>> >> +.min_access_size = 4,
>>> >> +.max_access_size = 4,
>>> >> +.unaligned = false,
>>> >> +},
>>> >> +};
>>> >
>>> > Could you pls add some comments explaining why is DEVICE_NATIVE_ENDIAN
>>> > appropriate here?  Most of these cases are plain "we never bothered
>>> > about cross-endian setups". Some are "there's a mix of different
>>> > endian-ness values, need to handle in a special way".
>>> >
>>> > I suspect you really need DEVICE_LITTLE_ENDIAN.
>>> >
>>>
>>> That MemoryRegion c

Re: [Qemu-devel] [PATCH v6 1/3] pci: Add support for Designware IP block

2018-02-13 Thread Andrey Smirnov
On Tue, Feb 13, 2018 at 2:15 PM, Michael S. Tsirkin <m...@redhat.com> wrote:
> On Tue, Feb 13, 2018 at 12:24:40PM -0800, Andrey Smirnov wrote:
>> On Tue, Feb 13, 2018 at 10:13 AM, Michael S. Tsirkin <m...@redhat.com> wrote:
>> > On Tue, Feb 13, 2018 at 09:07:10AM -0800, Andrey Smirnov wrote:
>> >> +static void designware_pcie_root_class_init(ObjectClass *klass, void 
>> >> *data)
>> >> +{
>> >> +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> >> +DeviceClass *dc = DEVICE_CLASS(klass);
>> >> +
>> >> +set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>> >> +
>> >> +k->vendor_id = PCI_VENDOR_ID_SYNOPSYS;
>> >> +k->device_id = 0xABCD;
>> >> +k->revision = 0;
>> >> +k->class_id = PCI_CLASS_BRIDGE_PCI;
>> >> +k->is_express = true;
>> >> +k->is_bridge = true;
>> >> +k->exit = pci_bridge_exitfn;
>> >> +k->realize = designware_pcie_root_realize;
>> >> +k->config_read = designware_pcie_root_config_read;
>> >> +k->config_write = designware_pcie_root_config_write;
>> >> +
>> >> +dc->reset = pci_bridge_reset;
>> >> +/*
>> >> + * PCI-facing part of the host bridge, not usable without the
>> >> + * host-facing part, which can't be device_add'ed, yet.
>> >> + */
>> >> +dc->user_creatable = false;
>> >> +dc->vmsd = _designware_pcie_root;
>> >> +}
>> >> +
>> >> +static uint64_t designware_pcie_host_mmio_read(void *opaque, hwaddr addr,
>> >> +   unsigned int size)
>> >> +{
>> >> +PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
>> >> +PCIDevice *device = pci_find_device(pci->bus, 0, 0);
>> >> +
>> >> +return pci_host_config_read_common(device,
>> >> +   addr,
>> >> +   pci_config_size(device),
>> >> +   size);
>> >> +}
>> >> +
>> >> +static void designware_pcie_host_mmio_write(void *opaque, hwaddr addr,
>> >> +uint64_t val, unsigned int 
>> >> size)
>> >> +{
>> >> +PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
>> >> +PCIDevice *device = pci_find_device(pci->bus, 0, 0);
>> >> +
>> >> +return pci_host_config_write_common(device,
>> >> +addr,
>> >> +pci_config_size(device),
>> >> +val, size);
>> >> +}
>> >> +
>> >> +static const MemoryRegionOps designware_pci_mmio_ops = {
>> >> +.read   = designware_pcie_host_mmio_read,
>> >> +.write  = designware_pcie_host_mmio_write,
>> >> +.endianness = DEVICE_NATIVE_ENDIAN,
>> >> +.impl = {
>> >> +/*
>> >> + * Our device would not work correctly if the guest was doing
>> >> + * unaligned access. This might not be a limitation on the real
>> >> + * device but in practice there is no reason for a guest to 
>> >> access
>> >> + * this device unaligned.
>> >> + */
>> >> +.min_access_size = 4,
>> >> +.max_access_size = 4,
>> >> +.unaligned = false,
>> >> +},
>> >> +};
>> >
>> > Could you pls add some comments explaining why is DEVICE_NATIVE_ENDIAN
>> > appropriate here?  Most of these cases are plain "we never bothered
>> > about cross-endian setups". Some are "there's a mix of different
>> > endian-ness values, need to handle in a special way".
>> >
>> > I suspect you really need DEVICE_LITTLE_ENDIAN.
>> >
>>
>> That MemoryRegion corresponds to a register file permanently mapped
>> into CPU's address space, so my assumption is that SoC designers will
>> wire it according to CPUs endianness be it big or little. I am not
>> aware of any big-endian CPU based SoC on the market using Designware's
>> IP block, so I don't think there are any precedent confirming or
>> denying correctness of my assumption. IMHO, this is also the reason
>> why all of Linux driver code for that IP assumes little endianness.
>
> IMHO if Linux driver code does cpu_to_le then it seems best to be
> consistent with that.
>

Well, all of the DW code does so implicitly by using readl()/writel()
helpers which will perform cpu_to_le/le_to_cpu under the hood. But is
seems to me that it could be either because the access does have to be
LE always or simply because readl()/writel() are goto memory helpers
on ARM/LE-platforms.

FWIW: Somewhat similar precedent of MIPS/Boston machine can serve as
counter-example to my assumption, since Xilinx PCIE IP there seem to
be wired to be LE despite being attached to BE CPU.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v6 1/3] pci: Add support for Designware IP block

2018-02-13 Thread Andrey Smirnov
On Tue, Feb 13, 2018 at 10:13 AM, Michael S. Tsirkin <m...@redhat.com> wrote:
> On Tue, Feb 13, 2018 at 09:07:10AM -0800, Andrey Smirnov wrote:
>> +static void designware_pcie_root_class_init(ObjectClass *klass, void *data)
>> +{
>> +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> +DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>> +
>> +k->vendor_id = PCI_VENDOR_ID_SYNOPSYS;
>> +k->device_id = 0xABCD;
>> +k->revision = 0;
>> +k->class_id = PCI_CLASS_BRIDGE_PCI;
>> +k->is_express = true;
>> +k->is_bridge = true;
>> +k->exit = pci_bridge_exitfn;
>> +k->realize = designware_pcie_root_realize;
>> +k->config_read = designware_pcie_root_config_read;
>> +k->config_write = designware_pcie_root_config_write;
>> +
>> +dc->reset = pci_bridge_reset;
>> +/*
>> + * PCI-facing part of the host bridge, not usable without the
>> + * host-facing part, which can't be device_add'ed, yet.
>> + */
>> +dc->user_creatable = false;
>> +dc->vmsd = _designware_pcie_root;
>> +}
>> +
>> +static uint64_t designware_pcie_host_mmio_read(void *opaque, hwaddr addr,
>> +   unsigned int size)
>> +{
>> +PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
>> +PCIDevice *device = pci_find_device(pci->bus, 0, 0);
>> +
>> +return pci_host_config_read_common(device,
>> +   addr,
>> +   pci_config_size(device),
>> +   size);
>> +}
>> +
>> +static void designware_pcie_host_mmio_write(void *opaque, hwaddr addr,
>> +uint64_t val, unsigned int size)
>> +{
>> +PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
>> +PCIDevice *device = pci_find_device(pci->bus, 0, 0);
>> +
>> +return pci_host_config_write_common(device,
>> +addr,
>> +pci_config_size(device),
>> +val, size);
>> +}
>> +
>> +static const MemoryRegionOps designware_pci_mmio_ops = {
>> +.read   = designware_pcie_host_mmio_read,
>> +.write  = designware_pcie_host_mmio_write,
>> +.endianness = DEVICE_NATIVE_ENDIAN,
>> +.impl = {
>> +/*
>> + * Our device would not work correctly if the guest was doing
>> + * unaligned access. This might not be a limitation on the real
>> + * device but in practice there is no reason for a guest to access
>> + * this device unaligned.
>> + */
>> +.min_access_size = 4,
>> +.max_access_size = 4,
>> +.unaligned = false,
>> +},
>> +};
>
> Could you pls add some comments explaining why is DEVICE_NATIVE_ENDIAN
> appropriate here?  Most of these cases are plain "we never bothered
> about cross-endian setups". Some are "there's a mix of different
> endian-ness values, need to handle in a special way".
>
> I suspect you really need DEVICE_LITTLE_ENDIAN.
>

That MemoryRegion corresponds to a register file permanently mapped
into CPU's address space, so my assumption is that SoC designers will
wire it according to CPUs endianness be it big or little. I am not
aware of any big-endian CPU based SoC on the market using Designware's
IP block, so I don't think there are any precedent confirming or
denying correctness of my assumption. IMHO, this is also the reason
why all of Linux driver code for that IP assumes little endianness.

I can't say that I testing this code against a big-endian guest/CPU,
but that is primarily due to the fact that there's no real use case
and any test set up I can put toghere would be a contrived example
pointlessly proving my point.

Anyway, I am more than happy to switch it to use DEVICE_LITTLE_ENDIAN,
I just don't know if doing so is any more justified than keeping it
DEVICE_NATIVE_ENDIAN.

Thanks,
Andrey Smirnov



[Qemu-devel] [PATCH v6 1/3] pci: Add support for Designware IP block

2018-02-13 Thread Andrey Smirnov
Add code needed to get a functional PCI subsytem when using in
conjunction with upstream Linux guest (4.13+). Tested to work against
"e1000e" (network adapter, using MSI interrupts) as well as
"usb-ehci" (USB controller, using legacy PCI interrupts).

Based on "i.MX6 Applications Processor Reference Manual" (Document
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak  |   2 +
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/pci-host/designware.c | 755 +++
 hw/pci-host/Makefile.objs|   2 +
 5 files changed, 863 insertions(+)
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/pci-host/designware.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index ca34cf4462..877bb7dd36 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -133,3 +133,5 @@ CONFIG_GPIO_KEY=y
 CONFIG_MSF2=y
 CONFIG_FW_CFG_DMA=y
 CONFIG_XILINX_AXI=y
+CONFIG_PCI_DESIGNWARE=y
+
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
new file mode 100644
index 00..a4f2c0695b
--- /dev/null
+++ b/include/hw/pci-host/designware.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Designware PCIe IP block emulation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DESIGNWARE_H
+#define DESIGNWARE_H
+
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pcie_host.h"
+#include "hw/pci/pci_bridge.h"
+
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
+#define DESIGNWARE_PCIE_HOST(obj) \
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
+
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
+#define DESIGNWARE_PCIE_ROOT(obj) \
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
+
+struct DesignwarePCIERoot;
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
+
+typedef struct DesignwarePCIEViewport {
+DesignwarePCIERoot *root;
+
+MemoryRegion cfg;
+MemoryRegion mem;
+
+uint64_t base;
+uint64_t target;
+uint32_t limit;
+uint32_t cr[2];
+
+bool inbound;
+} DesignwarePCIEViewport;
+
+typedef struct DesignwarePCIEMSIBank {
+uint32_t enable;
+uint32_t mask;
+uint32_t status;
+} DesignwarePCIEMSIBank;
+
+typedef struct DesignwarePCIEMSI {
+uint64_t base;
+MemoryRegion iomem;
+
+#define DESIGNWARE_PCIE_NUM_MSI_BANKS1
+
+DesignwarePCIEMSIBank intr[DESIGNWARE_PCIE_NUM_MSI_BANKS];
+} DesignwarePCIEMSI;
+
+struct DesignwarePCIERoot {
+PCIBridge parent_obj;
+
+uint32_t atu_viewport;
+
+#define DESIGNWARE_PCIE_VIEWPORT_OUTBOUND0
+#define DESIGNWARE_PCIE_VIEWPORT_INBOUND 1
+#define DESIGNWARE_PCIE_NUM_VIEWPORTS4
+
+DesignwarePCIEViewport viewports[2][DESIGNWARE_PCIE_NUM_VIEWPORTS];
+DesignwarePCIEMSI msi;
+};
+
+typedef struct DesignwarePCIEHost {
+PCIHostState parent_obj;
+
+DesignwarePCIERoot root;
+
+struct {
+AddressSpace address_space;
+MemoryRegion address_space_root;
+
+MemoryRegion memory;
+MemoryRegion io;
+
+qemu_irq irqs[4];
+} pci;
+
+MemoryRegion mmio;
+} DesignwarePCIEHost;
+
+#endif  /* DESIGNWARE_H */
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 35df1874a9..23fefe1bc6 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -266,4 +266,6 @@
 #define PCI_VENDOR_ID_TEWS   0x1498
 #define PCI_DEVICE_ID_TEWS_TPCI200   0x30C8
 
+#define PCI_VENDOR_ID_SYNOPSYS   0x16C3
+
 #endif
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c

[Qemu-devel] [PATCH v6 2/3] i.MX: Add i.MX7 SOC implementation.

2018-02-13 Thread Andrey Smirnov
The following interfaces are partially or fully emulated:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller

Tested to boot and work with upstream Linux (4.13+) guest.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak |   1 +
 include/hw/arm/fsl-imx7.h   | 222 +++
 hw/arm/fsl-imx7.c   | 580 
 hw/arm/Makefile.objs|   2 +
 4 files changed, 805 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 hw/arm/fsl-imx7.c

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 877bb7dd36..d8a360aef7 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -119,6 +119,7 @@ CONFIG_ALLWINNER_A10=y
 CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
+CONFIG_FSL_IMX7=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
new file mode 100644
index 00..d848262bfd
--- /dev/null
+++ b/include/hw/arm/fsl-imx7.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 SoC definitions
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef FSL_IMX7_H
+#define FSL_IMX7_H
+
+#include "hw/arm/arm.h"
+#include "hw/cpu/a15mpcore.h"
+#include "hw/intc/imx_gpcv2.h"
+#include "hw/misc/imx7_ccm.h"
+#include "hw/misc/imx7_snvs.h"
+#include "hw/misc/imx7_gpr.h"
+#include "hw/misc/imx6_src.h"
+#include "hw/misc/imx2_wdt.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/char/imx_serial.h"
+#include "hw/timer/imx_gpt.h"
+#include "hw/timer/imx_epit.h"
+#include "hw/i2c/imx_i2c.h"
+#include "hw/gpio/imx_gpio.h"
+#include "hw/sd/sdhci.h"
+#include "hw/ssi/imx_spi.h"
+#include "hw/net/imx_fec.h"
+#include "hw/pci-host/designware.h"
+#include "hw/usb/chipidea.h"
+#include "exec/memory.h"
+#include "cpu.h"
+
+#define TYPE_FSL_IMX7 "fsl,imx7"
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
+
+enum FslIMX7Configuration {
+FSL_IMX7_NUM_CPUS = 2,
+FSL_IMX7_NUM_UARTS= 7,
+FSL_IMX7_NUM_ETHS = 2,
+FSL_IMX7_ETH_NUM_TX_RINGS = 3,
+FSL_IMX7_NUM_USDHCS   = 3,
+FSL_IMX7_NUM_WDTS = 4,
+FSL_IMX7_NUM_GPTS = 4,
+FSL_IMX7_NUM_IOMUXCS  = 2,
+FSL_IMX7_NUM_GPIOS= 7,
+FSL_IMX7_NUM_I2CS = 4,
+FSL_IMX7_NUM_ECSPIS   = 4,
+FSL_IMX7_NUM_USBS = 3,
+FSL_IMX7_NUM_ADCS = 2,
+};
+
+typedef struct FslIMX7State {
+/*< private >*/
+DeviceStateparent_obj;
+
+/*< public >*/
+ARMCPU cpu[FSL_IMX7_NUM_CPUS];
+A15MPPrivState a7mpcore;
+IMXGPTStategpt[FSL_IMX7_NUM_GPTS];
+IMXGPIOState   gpio[FSL_IMX7_NUM_GPIOS];
+IMX7CCMState   ccm;
+IMX7AnalogStateanalog;
+IMX7SNVSState  snvs;
+IMXGPCv2State  gpcv2;
+IMXSPIStatespi[FSL_IMX7_NUM_ECSPIS];
+IMXI2CStatei2c[FSL_IMX7_NUM_I2CS];
+IMXSerialState uart[FSL_IMX7_NUM_UARTS];
+IMXFECStateeth[FSL_IMX7_NUM_ETHS];
+SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
+IMX2WdtState   wdt[FSL_IMX7_NUM_WDTS];
+IMX7GPRState   gpr;
+ChipideaState  usb[FSL_IMX7_NUM_USBS];
+DesignwarePCIEHost pcie;
+} FslIMX7State;
+
+enu

[Qemu-devel] [PATCH v6 0/3] Initial i.MX7 support

2018-02-13 Thread Andrey Smirnov
Hi everyone,

This v6 of the patch series containing the work that I've done in
order to enable support for i.MX7 emulation in QEMU.

As the one before last commit in the series states the supported i.MX7
features are:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller
* 3 USB controllers
* 1 LCD controller
* 1 ARMv7 DAP IP block

Feedback is welcome!

Changes since [v5]:

- Rebase patchest on top of latest QEMU master, so now the
  patchset is down to three patches

- Reverted the change to use pci_data_* functions becuase the
  patch supporting this change was causing trouble

- Fixed endiannes of MSI and configuration space accessors to be
  LITTLE_ENDIAN

Changes since [v4]:

- Rebase patchest on top of latest QEMU master

- Reworked PCIE emulation code to create MemoryRegions
  only once

- Fixed incorrect usages of PCI instead of PCIE

- Fixed device class reported by PCIE bridge

- Added patch to make pci_data_read() and pci_data_write() usable
  for PCIE devices as well

- Converted PCIE code to use pci_data_read() and pci_data_write()

- Added VMStateDescription code for PCIE

- Collected Reviewed-by tag from Philippe

Changes since [v3]:

- Changes to FEC were split into a separate set and merged to master

- Patchest is rebased on latest master

- Converted to use PSCI DT fixup code that is shared with virt
  platform (now relocated to live in arm/boot.c)

- Large number of dummy block were converted to use
  create_unimplemented_device() as opposed to its own dedicated
  type

- Incorporated varios small feedback items

- Collected Reviewed-by tags from Peter

Changes since [v2]:

- Added stubs for more blocks that were causing memory
  transactions when booting Linux guest as were revealed by
  additional testing of the patchest

- Added proper USB emulation code, so now it should be possible to
  emulated guest's USB bus

Changes since [v1]:

- Patchset no longer relies on "ignore_memory_transaction_failures = false"
  for its functionality

- As a consequnce of implementing the above a number of patches
  implementing dummy IP block emulation as well as PCIe emulation
  patches that I alluded to in [v1] are now included in this patch
  series

- "has_el3" property is no longer being set to "false" as a part
  of intialization of A7 CPU. I couldn't reproduce the issues that
  I thought I was having, so I just dropped that code.

- A number of smaller feedback items from Peter and other has been
  incorporated into the patches.


Thanks,
Andrey Smirnov

[v5] https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg01558.html
[v4] https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg03264.html
[v3] https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg04236.html
[v2] https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05516.html
[v1] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg04770.html

Andrey Smirnov (3):
  pci: Add support for Designware IP block
  i.MX: Add i.MX7 SOC implementation.
  Implement support for i.MX7 Sabre board

 default-configs/arm-softmmu.mak  |   3 +
 include/hw/arm/fsl-imx7.h| 222 
 include/hw/pci-host/designware.h | 102 ++
 include/hw/pci/pci_ids.h |   2 +
 hw/arm/fsl-imx7.c| 580 ++
 hw/arm/mcimx7d-sabre.c   |  90 +
 hw/pci-host/designware.c | 755 +++
 hw/arm/Makefile.objs |   3 +
 hw/pci-host/Makefile.objs|   2 +
 9 files changed, 1759 insertions(+)
 create mode 100644 include/hw/arm/fsl-imx7.h
 create mode 100644 include/hw/pci-host/designware.h
 create mode 100644 hw/arm/fsl-imx7.c
 create mode 100644 hw/arm/mcimx7d-sabre.c
 create mode 100644 hw/pci-host/designware.c

-- 
2.14.3




Re: [Qemu-devel] [PATCH v5 10/14] pci: Add support for Designware IP block

2018-02-08 Thread Andrey Smirnov
On Thu, Feb 8, 2018 at 12:33 PM, Michael S. Tsirkin <m...@redhat.com> wrote:
> On Thu, Feb 08, 2018 at 12:22:53PM -0800, Andrey Smirnov wrote:
>> On Thu, Feb 8, 2018 at 12:11 PM, Michael S. Tsirkin <m...@redhat.com> wrote:
>> > On Thu, Feb 08, 2018 at 12:03:04PM -0800, Andrey Smirnov wrote:
>> >> >> +#define PCIE_PORT_LINK_CONTROL  0x710
>> >> >> +
>> >> >> +#define PCIE_PHY_DEBUG_R1   0x72C
>> >> >> +#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP  BIT(4)
>> >> >> +
>> >> >> +#define PCIE_LINK_WIDTH_SPEED_CONTROL   0x80C
>> >> >> +#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
>> >> >> +
>> >> >> +#define PCIE_MSI_ADDR_LO0x820
>> >> >> +#define PCIE_MSI_ADDR_HI0x824
>> >> >> +#define PCIE_MSI_INTR0_ENABLE   0x828
>> >> >> +#define PCIE_MSI_INTR0_MASK 0x82C
>> >> >> +#define PCIE_MSI_INTR0_STATUS   0x830
>> >> >> +
>> >> >> +#define PCIE_ATU_VIEWPORT   0x900
>> >> >> +#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
>> >> >> +#define PCIE_ATU_REGION_OUTBOUND(0x0 << 31)
>> >> >> +#define PCIE_ATU_REGION_INDEX2  (0x2 << 0)
>> >> >> +#define PCIE_ATU_REGION_INDEX1  (0x1 << 0)
>> >> >> +#define PCIE_ATU_REGION_INDEX0  (0x0 << 0)
>> >> >> +#define PCIE_ATU_CR10x904
>> >> >> +#define PCIE_ATU_TYPE_MEM   (0x0 << 0)
>> >> >> +#define PCIE_ATU_TYPE_IO(0x2 << 0)
>> >> >> +#define PCIE_ATU_TYPE_CFG0  (0x4 << 0)
>> >> >> +#define PCIE_ATU_TYPE_CFG1  (0x5 << 0)
>> >> >> +#define PCIE_ATU_CR20x908
>> >> >> +#define PCIE_ATU_ENABLE (0x1 << 31)
>> >> >> +#define PCIE_ATU_BAR_MODE_ENABLE(0x1 << 30)
>> >> >> +#define PCIE_ATU_LOWER_BASE 0x90C
>> >> >> +#define PCIE_ATU_UPPER_BASE 0x910
>> >> >> +#define PCIE_ATU_LIMIT  0x914
>> >> >> +#define PCIE_ATU_LOWER_TARGET   0x918
>> >> >> +#define PCIE_ATU_BUS(x) (((x) >> 24) & 0xff)
>> >> >> +#define PCIE_ATU_DEVFN(x)   (((x) >> 16) & 0xff)
>> >> >> +#define PCIE_ATU_UPPER_TARGET   0x91C
>> >
>> > Can you avoid a PCIE prefix for this btw?
>> >
>>
>> That's how those constants were named in Linux kernel, but yeah, I'll
>> add a prefix to them.
>>
>> Thanks,
>> Andrey Smirnov
>
> In that case you should not copy it into your file.
> Stuff from linux kernel should be imported into standard-headers.
>

Just to be sure we are on the same page, this is the file I am talking about:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/dwc/pcie-designware.h?h=v4.15

you want me to put it in standard-headers/linux and get those
constants from there?

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v5 10/14] pci: Add support for Designware IP block

2018-02-08 Thread Andrey Smirnov
On Thu, Feb 8, 2018 at 12:11 PM, Michael S. Tsirkin <m...@redhat.com> wrote:
> On Thu, Feb 08, 2018 at 12:03:04PM -0800, Andrey Smirnov wrote:
>> >> +#define PCIE_PORT_LINK_CONTROL  0x710
>> >> +
>> >> +#define PCIE_PHY_DEBUG_R1   0x72C
>> >> +#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP  BIT(4)
>> >> +
>> >> +#define PCIE_LINK_WIDTH_SPEED_CONTROL   0x80C
>> >> +#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
>> >> +
>> >> +#define PCIE_MSI_ADDR_LO0x820
>> >> +#define PCIE_MSI_ADDR_HI0x824
>> >> +#define PCIE_MSI_INTR0_ENABLE   0x828
>> >> +#define PCIE_MSI_INTR0_MASK 0x82C
>> >> +#define PCIE_MSI_INTR0_STATUS   0x830
>> >> +
>> >> +#define PCIE_ATU_VIEWPORT   0x900
>> >> +#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
>> >> +#define PCIE_ATU_REGION_OUTBOUND(0x0 << 31)
>> >> +#define PCIE_ATU_REGION_INDEX2  (0x2 << 0)
>> >> +#define PCIE_ATU_REGION_INDEX1  (0x1 << 0)
>> >> +#define PCIE_ATU_REGION_INDEX0  (0x0 << 0)
>> >> +#define PCIE_ATU_CR10x904
>> >> +#define PCIE_ATU_TYPE_MEM   (0x0 << 0)
>> >> +#define PCIE_ATU_TYPE_IO(0x2 << 0)
>> >> +#define PCIE_ATU_TYPE_CFG0  (0x4 << 0)
>> >> +#define PCIE_ATU_TYPE_CFG1  (0x5 << 0)
>> >> +#define PCIE_ATU_CR20x908
>> >> +#define PCIE_ATU_ENABLE (0x1 << 31)
>> >> +#define PCIE_ATU_BAR_MODE_ENABLE(0x1 << 30)
>> >> +#define PCIE_ATU_LOWER_BASE 0x90C
>> >> +#define PCIE_ATU_UPPER_BASE 0x910
>> >> +#define PCIE_ATU_LIMIT  0x914
>> >> +#define PCIE_ATU_LOWER_TARGET   0x918
>> >> +#define PCIE_ATU_BUS(x) (((x) >> 24) & 0xff)
>> >> +#define PCIE_ATU_DEVFN(x)   (((x) >> 16) & 0xff)
>> >> +#define PCIE_ATU_UPPER_TARGET   0x91C
>
> Can you avoid a PCIE prefix for this btw?
>

That's how those constants were named in Linux kernel, but yeah, I'll
add a prefix to them.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v5 10/14] pci: Add support for Designware IP block

2018-02-08 Thread Andrey Smirnov
On Thu, Feb 8, 2018 at 9:45 AM, Michael S. Tsirkin <m...@redhat.com> wrote:
> On Tue, Feb 06, 2018 at 08:24:34PM -0800, Andrey Smirnov wrote:
>> Add code needed to get a functional PCI subsytem when using in
>> conjunction with upstream Linux guest (4.13+). Tested to work against
>> "e1000e" (network adapter, using MSI interrupts) as well as
>> "usb-ehci" (USB controller, using legacy PCI interrupts).
>>
>> Based on "i.MX6 Applications Processor Reference Manual" (Document
>> Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
>> kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)
>>
>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>> Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
>> Cc: Michael S. Tsirkin <m...@redhat.com>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.org
>> Cc: yurov...@gmail.com
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> ---
>>  default-configs/arm-softmmu.mak  |   2 +
>>  hw/pci-host/Makefile.objs|   2 +
>>  hw/pci-host/designware.c | 759 
>> +++
>>  include/hw/pci-host/designware.h |  97 +
>>  include/hw/pci/pci_ids.h |   2 +
>>  5 files changed, 862 insertions(+)
>>  create mode 100644 hw/pci-host/designware.c
>>  create mode 100644 include/hw/pci-host/designware.h
>>
>> diff --git a/default-configs/arm-softmmu.mak 
>> b/default-configs/arm-softmmu.mak
>> index b0d6e65038..0c5ae914ed 100644
>> --- a/default-configs/arm-softmmu.mak
>> +++ b/default-configs/arm-softmmu.mak
>> @@ -132,3 +132,5 @@ CONFIG_GPIO_KEY=y
>>  CONFIG_MSF2=y
>>  CONFIG_FW_CFG_DMA=y
>>  CONFIG_XILINX_AXI=y
>> +CONFIG_PCI_DESIGNWARE=y
>> +
>> diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
>> index 4b69f737b5..6d6597c065 100644
>> --- a/hw/pci-host/Makefile.objs
>> +++ b/hw/pci-host/Makefile.objs
>> @@ -17,3 +17,5 @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
>>  common-obj-$(CONFIG_PCI_Q35) += q35.o
>>  common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
>>  common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
>> +
>> +common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
>> diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
>> new file mode 100644
>> index 00..551a881af0
>> --- /dev/null
>> +++ b/hw/pci-host/designware.c
>> @@ -0,0 +1,759 @@
>> +/*
>> + * Copyright (c) 2018, Impinj, Inc.
>> + *
>> + * Designware PCIe IP block emulation
>> + *
>> + * This library is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2 of the License, or (at your option) any later version.
>> + *
>> + * This library is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with this library; if not, see
>> + * <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qapi/error.h"
>> +#include "hw/pci/msi.h"
>> +#include "hw/pci/pci_bridge.h"
>> +#include "hw/pci/pci_host.h"
>> +#include "hw/pci/pcie_port.h"
>> +#include "hw/pci-host/designware.h"
>> +
>> +#define PCIE_PORT_LINK_CONTROL  0x710
>> +
>> +#define PCIE_PHY_DEBUG_R1   0x72C
>> +#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP  BIT(4)
>> +
>> +#define PCIE_LINK_WIDTH_SPEED_CONTROL   0x80C
>> +#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
>> +
>> +#define PCIE_MSI_ADDR_LO0x820
>> +#define PCIE_MSI_ADDR_HI0x824
>> +#define PCIE_MSI_INTR0_ENABLE   0x828
>> +#define PCIE_MSI_INTR0_MASK 0x82C
>> +#define PCIE_MSI_INTR0_STATUS   0x830
>> +
>> +#define PCIE_ATU_VIEWPORT   0x900
>> +#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
>> +#define PCIE_ATU_REGION_OUTBOUND(0x0 << 31)
>> +#define PCIE_ATU_REGION_INDEX2  (0x2 << 0)
>

Re: [Qemu-devel] [PATCH v5 09/14] pci: Use pci_config_size in pci_data_* accessors

2018-02-08 Thread Andrey Smirnov
On Thu, Feb 8, 2018 at 9:34 AM, Michael S. Tsirkin <m...@redhat.com> wrote:
> On Thu, Feb 08, 2018 at 05:20:53PM +, Peter Maydell wrote:
>> On 7 February 2018 at 04:24, Andrey Smirnov <andrew.smir...@gmail.com> wrote:
>> > Use pci_config_size (as opposed to PCI_CONFIG_SPACE_SIZE) in
>> > pci_data_read() and pci_data_write(), so this function would work for
>> > both classic PCI and PCIe use-cases.
>> >
>> > Cc: Peter Maydell <peter.mayd...@linaro.org>
>> > Cc: Jason Wang <jasow...@redhat.com>
>> > Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>> > Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
>> > Cc: Michael S. Tsirkin <m...@redhat.com>
>> > Cc: qemu-devel@nongnu.org
>> > Cc: qemu-...@nongnu.org
>> > Cc: yurov...@gmail.com
>> > Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> > ---
>> >  hw/pci/pci_host.c | 13 +
>> >  1 file changed, 9 insertions(+), 4 deletions(-)
>> >
>> > diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
>> > index 5eaa935cb5..ea52ea07cd 100644
>> > --- a/hw/pci/pci_host.c
>> > +++ b/hw/pci/pci_host.c
>> > @@ -89,30 +89,35 @@ uint32_t pci_host_config_read_common(PCIDevice 
>> > *pci_dev, uint32_t addr,
>> >  void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
>> >  {
>> >  PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr);
>> > -uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1);
>> > +uint32_t config_addr;
>> >
>> >  if (!pci_dev) {
>> >  return;
>> >  }
>> >
>> > +config_addr = addr & (pci_config_size(pci_dev) - 1);
>> > +
>> >  PCI_DPRINTF("%s: %s: addr=%02" PRIx32 " val=%08" PRIx32 " len=%d\n",
>> >  __func__, pci_dev->name, config_addr, val, len);
>> > -pci_host_config_write_common(pci_dev, config_addr, 
>> > PCI_CONFIG_SPACE_SIZE,
>> > +pci_host_config_write_common(pci_dev, config_addr,
>> > + pci_config_size(pci_dev),
>> >   val, len);
>> >  }
>> >
>> >  uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
>> >  {
>> >  PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr);
>> > -uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1);
>> > +uint32_t config_addr;
>> >  uint32_t val;
>> >
>> >  if (!pci_dev) {
>> >  return ~0x0;
>> >  }
>> >
>> > +config_addr = addr & (pci_config_size(pci_dev) - 1);
>> > +
>> >  val = pci_host_config_read_common(pci_dev, config_addr,
>> > -  PCI_CONFIG_SPACE_SIZE, len);
>> > +  pci_config_size(pci_dev), len);
>> >  PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
>> >  __func__, pci_dev->name, config_addr, val, len);
>> >
>>
>> I've just discovered that this breaks the e1000e-test:
>>
>> $ (cd build/clang; QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64
>> ./tests/e1000e-test)
>> /x86_64/e1000e/init: **
>> ERROR:/home/petmay01/linaro/qemu-from-laptop/qemu/tests/e1000e-test.c:118:e1000e_device_find:
>> 'e1000e_dev' should not be NULL
>>
>> Any idea what's going on here?
>>

Peter:

Don't really have a good idea what's going on, but I am guessing this
change broke affected pci_host_data_* methods in negative way.

>> thanks
>> -- PMM
>
> I'm yet to review these patches, but IIRC pci_data_read and friends
> aren't designed with pcie in mind - they implement the classic pci
> config space.
>
> I'd like to see more justification about how these are now going
> to be used.
>

Michael:

My only justification for this change was suggestion from Marcel to
use pci_data_* functions, instead of calling pci_host_config_*_common
explicitly in designware.c introduced in next patch in the series. My
v4 patches incorrectly limited config space size to 256, so such
replacement didn't require this patch, but switching pci_data_* to use
pci_config_size() seemed harmless enough. I am more than happy to got
back to using pci_host_config_*_common in designware.c and dropping
this patch.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v5 12/14] i.MX: Add i.MX7 SOC implementation.

2018-02-08 Thread Andrey Smirnov
On Thu, Feb 8, 2018 at 5:26 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:
> On 7 February 2018 at 04:24, Andrey Smirnov <andrew.smir...@gmail.com> wrote:
>> The following interfaces are partially or fully emulated:
>
> Hi Andrey. I was just going through this series to apply to
> target-arm.next, and I noticed that fsl-imx7.c is GPL-2-or-later,
> but fsl-imx7.h is GPL-2-only. Is that intentional?
>
> If this is just an accidental error, and you send an email to
> say you meant 2-or-later, then I can fix this in my target-arm
> tree by copying the license paragraphs from fsl-imx7.c to fsl-imx7.h.
>

This is just a mistake on my part. Feel free to change to whatever
makes most sense.

Thanks,
Andrey Smrinov



Re: [Qemu-devel] [PATCH v5 00/14] Initial i.MX7 support

2018-02-08 Thread Andrey Smirnov
On Thu, Feb 8, 2018 at 5:49 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:
> On 7 February 2018 at 04:24, Andrey Smirnov <andrew.smir...@gmail.com> wrote:
>> Hi everyone,
>>
>> This v5 of the patch series containing the work that I've done in
>> order to enable support for i.MX7 emulation in QEMU.
>
> Thanks; I'm applying this to target-arm.next. There are a few minor
> tweaks I'm going to make in the process, but I think that's better
> than making you do yet another respin. Those changes are:
>  * dropped stray blank-line-at-end-of-file from a few patches
>  * fixed a couple of over-80-columnns lines
>  * added a ESDHC_UNDOCUMENTED_REG27 define as suggested by Philippe
>(I didn't reorder the switches to put 'default' last though, as
>that didn't seem necessary to me)
>
> If you get back to me today about the GPL-2-vs-2-or-later question
> for patch 13 I'll make that change too. Otherwise I'll drop 13
> and 14 for the moment.
>

Awesome, thanks!

Andrey Smirnov



[Qemu-devel] [PATCH v5 10/14] pci: Add support for Designware IP block

2018-02-06 Thread Andrey Smirnov
Add code needed to get a functional PCI subsytem when using in
conjunction with upstream Linux guest (4.13+). Tested to work against
"e1000e" (network adapter, using MSI interrupts) as well as
"usb-ehci" (USB controller, using legacy PCI interrupts).

Based on "i.MX6 Applications Processor Reference Manual" (Document
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak  |   2 +
 hw/pci-host/Makefile.objs|   2 +
 hw/pci-host/designware.c | 759 +++
 include/hw/pci-host/designware.h |  97 +
 include/hw/pci/pci_ids.h |   2 +
 5 files changed, 862 insertions(+)
 create mode 100644 hw/pci-host/designware.c
 create mode 100644 include/hw/pci-host/designware.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b0d6e65038..0c5ae914ed 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -132,3 +132,5 @@ CONFIG_GPIO_KEY=y
 CONFIG_MSF2=y
 CONFIG_FW_CFG_DMA=y
 CONFIG_XILINX_AXI=y
+CONFIG_PCI_DESIGNWARE=y
+
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 4b69f737b5..6d6597c065 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -17,3 +17,5 @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
 common-obj-$(CONFIG_PCI_Q35) += q35.o
 common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
 common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
+
+common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
new file mode 100644
index 00..551a881af0
--- /dev/null
+++ b/hw/pci-host/designware.c
@@ -0,0 +1,759 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * Designware PCIe IP block emulation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/pci-host/designware.h"
+
+#define PCIE_PORT_LINK_CONTROL  0x710
+
+#define PCIE_PHY_DEBUG_R1   0x72C
+#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP  BIT(4)
+
+#define PCIE_LINK_WIDTH_SPEED_CONTROL   0x80C
+#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
+
+#define PCIE_MSI_ADDR_LO0x820
+#define PCIE_MSI_ADDR_HI0x824
+#define PCIE_MSI_INTR0_ENABLE   0x828
+#define PCIE_MSI_INTR0_MASK 0x82C
+#define PCIE_MSI_INTR0_STATUS   0x830
+
+#define PCIE_ATU_VIEWPORT   0x900
+#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
+#define PCIE_ATU_REGION_OUTBOUND(0x0 << 31)
+#define PCIE_ATU_REGION_INDEX2  (0x2 << 0)
+#define PCIE_ATU_REGION_INDEX1  (0x1 << 0)
+#define PCIE_ATU_REGION_INDEX0  (0x0 << 0)
+#define PCIE_ATU_CR10x904
+#define PCIE_ATU_TYPE_MEM   (0x0 << 0)
+#define PCIE_ATU_TYPE_IO(0x2 << 0)
+#define PCIE_ATU_TYPE_CFG0  (0x4 << 0)
+#define PCIE_ATU_TYPE_CFG1  (0x5 << 0)
+#define PCIE_ATU_CR20x908
+#define PCIE_ATU_ENABLE (0x1 << 31)
+#define PCIE_ATU_BAR_MODE_ENABLE(0x1 << 30)
+#define PCIE_ATU_LOWER_BASE 0x90C
+#define PCIE_ATU_UPPER_BASE 0x910
+#define PCIE_ATU_LIMIT  0x914
+#define PCIE_ATU_LOWER_TARGET   0x918
+#define PCIE_ATU_BUS(x) (((x) >> 24) & 0xff)
+#define PCIE_ATU_DEVFN(x)   (((x) >> 16) & 0xff)
+#define PCIE_ATU_UPPER_TARGET   0x91C
+
+static DesignwarePCIEHost *
+designware_pcie_root_to_host(DesignwarePCIERoot *root)
+{
+BusState *bus = qdev_get_parent_bus(DE

[Qemu-devel] [PATCH v5 09/14] pci: Use pci_config_size in pci_data_* accessors

2018-02-06 Thread Andrey Smirnov
Use pci_config_size (as opposed to PCI_CONFIG_SPACE_SIZE) in
pci_data_read() and pci_data_write(), so this function would work for
both classic PCI and PCIe use-cases.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/pci/pci_host.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 5eaa935cb5..ea52ea07cd 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -89,30 +89,35 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, 
uint32_t addr,
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
 {
 PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr);
-uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1);
+uint32_t config_addr;
 
 if (!pci_dev) {
 return;
 }
 
+config_addr = addr & (pci_config_size(pci_dev) - 1);
+
 PCI_DPRINTF("%s: %s: addr=%02" PRIx32 " val=%08" PRIx32 " len=%d\n",
 __func__, pci_dev->name, config_addr, val, len);
-pci_host_config_write_common(pci_dev, config_addr, PCI_CONFIG_SPACE_SIZE,
+pci_host_config_write_common(pci_dev, config_addr,
+ pci_config_size(pci_dev),
  val, len);
 }
 
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
 {
 PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr);
-uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1);
+uint32_t config_addr;
 uint32_t val;
 
 if (!pci_dev) {
 return ~0x0;
 }
 
+config_addr = addr & (pci_config_size(pci_dev) - 1);
+
 val = pci_host_config_read_common(pci_dev, config_addr,
-  PCI_CONFIG_SPACE_SIZE, len);
+  pci_config_size(pci_dev), len);
 PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
 __func__, pci_dev->name, config_addr, val, len);
 
-- 
2.14.3




[Qemu-devel] [PATCH v5 08/14] i.MX: Add implementation of i.MX7 GPR IP block

2018-02-06 Thread Andrey Smirnov
Add minimal code needed to allow upstream Linux guest to boot.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org>
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx7_gpr.c | 124 +
 hw/misc/trace-events   |   4 ++
 include/hw/misc/imx7_gpr.h |  28 ++
 4 files changed, 157 insertions(+)
 create mode 100644 hw/misc/imx7_gpr.c
 create mode 100644 include/hw/misc/imx7_gpr.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 019886912c..fce426eb75 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -36,6 +36,7 @@ obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_IMX) += imx2_wdt.o
 obj-$(CONFIG_IMX) += imx7_snvs.o
+obj-$(CONFIG_IMX) += imx7_gpr.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx7_gpr.c b/hw/misc/imx7_gpr.c
new file mode 100644
index 00..c2a9df29c6
--- /dev/null
+++ b/hw/misc/imx7_gpr.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 GPR IP block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Bare minimum emulation code needed to support being able to shut
+ * down linux guest gracefully.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx7_gpr.h"
+#include "qemu/log.h"
+#include "sysemu/sysemu.h"
+
+#include "trace.h"
+
+enum IMX7GPRRegisters {
+IOMUXC_GPR0  = 0x00,
+IOMUXC_GPR1  = 0x04,
+IOMUXC_GPR2  = 0x08,
+IOMUXC_GPR3  = 0x0c,
+IOMUXC_GPR4  = 0x10,
+IOMUXC_GPR5  = 0x14,
+IOMUXC_GPR6  = 0x18,
+IOMUXC_GPR7  = 0x1c,
+IOMUXC_GPR8  = 0x20,
+IOMUXC_GPR9  = 0x24,
+IOMUXC_GPR10 = 0x28,
+IOMUXC_GPR11 = 0x2c,
+IOMUXC_GPR12 = 0x30,
+IOMUXC_GPR13 = 0x34,
+IOMUXC_GPR14 = 0x38,
+IOMUXC_GPR15 = 0x3c,
+IOMUXC_GPR16 = 0x40,
+IOMUXC_GPR17 = 0x44,
+IOMUXC_GPR18 = 0x48,
+IOMUXC_GPR19 = 0x4c,
+IOMUXC_GPR20 = 0x50,
+IOMUXC_GPR21 = 0x54,
+IOMUXC_GPR22 = 0x58,
+};
+
+#define IMX7D_GPR1_IRQ_MASK BIT(12)
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASKBIT(13)
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASKBIT(14)
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK (0x3 << 13)
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK   BIT(17)
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK   BIT(18)
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK(0x3 << 17)
+
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI BIT(4)
+#define IMX7D_GPR12_PCIE_PHY_REFCLK_SEL BIT(5)
+#define IMX7D_GPR22_PCIE_PHY_PLL_LOCKED BIT(31)
+
+
+static uint64_t imx7_gpr_read(void *opaque, hwaddr offset, unsigned size)
+{
+trace_imx7_gpr_read(offset);
+
+if (offset == IOMUXC_GPR22) {
+return IMX7D_GPR22_PCIE_PHY_PLL_LOCKED;
+}
+
+return 0;
+}
+
+static void imx7_gpr_write(void *opaque, hwaddr offset,
+   uint64_t v, unsigned size)
+{
+trace_imx7_gpr_write(offset, v);
+}
+
+static const struct MemoryRegionOps imx7_gpr_ops = {
+.read = imx7_gpr_read,
+.write = imx7_gpr_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the
+ * real device but in practice there is no reason for a guest
+ * to access this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void imx7_gpr_init(Object *obj)
+{
+SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+IMX7GPRState *s = IMX7_GPR(obj);
+
+memory_region_init_io(>mmio, obj, _gpr_ops, s,
+  TYPE_IMX7_GPR, 64 * 1024);
+sysbus_init_mmio(sd, >mmio);
+}
+
+static void imx7_gpr_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc  = "i.MX7 General Purpose Registers Module";
+}
+
+static const TypeInfo imx7_gpr_info = {
+.name  = TYPE_IMX7_GPR,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(IMX7GPRState),
+.instance_init = imx7_gpr_init,
+.class_init= imx7_gpr_class_init,
+};
+
+static void imx7_gpr_register_type(void)
+{
+type_regi

[Qemu-devel] [PATCH v5 12/14] i.MX: Add i.MX7 SOC implementation.

2018-02-06 Thread Andrey Smirnov
The following interfaces are partially or fully emulated:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller

Tested to boot and work with upstream Linux (4.13+) guest.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   2 +
 hw/arm/fsl-imx7.c   | 580 
 include/hw/arm/fsl-imx7.h   | 221 +++
 4 files changed, 804 insertions(+)
 create mode 100644 hw/arm/fsl-imx7.c
 create mode 100644 include/hw/arm/fsl-imx7.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 0c5ae914ed..99fe1cd1fb 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -118,6 +118,7 @@ CONFIG_ALLWINNER_A10=y
 CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
+CONFIG_FSL_IMX7=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 1c896bafb4..1f306c6a19 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -20,3 +20,5 @@ obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
 obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
+
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
new file mode 100644
index 00..5e78f64ac4
--- /dev/null
+++ b/hw/arm/fsl-imx7.c
@@ -0,0 +1,580 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 SoC definitions
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * Based on hw/arm/fsl-imx6.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/fsl-imx7.h"
+#include "hw/misc/unimp.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+#define NAME_SIZE 20
+
+static void fsl_imx7_init(Object *obj)
+{
+BusState *sysbus = sysbus_get_default();
+FslIMX7State *s = FSL_IMX7(obj);
+char name[NAME_SIZE];
+int i;
+
+if (smp_cpus > FSL_IMX7_NUM_CPUS) {
+error_report("%s: Only %d CPUs are supported (%d requested)",
+ TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
+exit(1);
+}
+
+for (i = 0; i < smp_cpus; i++) {
+object_initialize(>cpu[i], sizeof(s->cpu[i]),
+  ARM_CPU_TYPE_NAME("cortex-a7"));
+snprintf(name, NAME_SIZE, "cpu%d", i);
+object_property_add_child(obj, name, OBJECT(>cpu[i]),
+  _fatal);
+}
+
+/*
+ * A7MPCORE
+ */
+object_initialize(>a7mpcore, sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
+qdev_set_parent_bus(DEVICE(>a7mpcore), sysbus);
+object_property_add_child(obj, "a7mpcore",
+  OBJECT(>a7mpcore), _fatal);
+
+/*
+ * GPIOs 1 to 7
+ */
+for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
+object_initialize(>gpio[i], sizeof(s->gpio[i]),
+  TYPE_IMX_GPIO);
+qdev_set_parent_bus(DEVICE(>gpio[i]), sysbus);
+snprintf(name, NAME_SIZE, "gpio%d", i);
+object_property_add_child(obj, name,
+  OBJECT(>gpio[i]), _fatal);
+}
+
+/*
+ * GPT1, 2, 3, 4
+ */
+for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
+object_initialize(>gpt[i], sizeof(s->gpt[i]), TYPE_IMX7_GPT);
+qdev_set_parent_bus(DEVICE(>gpt[i]), sysbus)

[Qemu-devel] [PATCH v5 07/14] i.MX: Add i.MX7 GPT variant

2018-02-06 Thread Andrey Smirnov
Add minimal code needed to allow upstream Linux guest to boot.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org>
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/timer/imx_gpt.c | 25 +
 include/hw/timer/imx_gpt.h |  1 +
 2 files changed, 26 insertions(+)

diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 4b9b54bf2e..65e4ee6bcf 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -113,6 +113,17 @@ static const IMXClk imx6_gpt_clocks[] = {
 CLK_HIGH,  /* 111 reference clock */
 };
 
+static const IMXClk imx7_gpt_clocks[] = {
+CLK_NONE,  /* 000 No clock source */
+CLK_IPG,   /* 001 ipg_clk, 532MHz*/
+CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
+CLK_EXT,   /* 011 External clock */
+CLK_32k,   /* 100 ipg_clk_32k */
+CLK_HIGH,  /* 101 reference clock */
+CLK_NONE,  /* 110 not defined */
+CLK_NONE,  /* 111 not defined */
+};
+
 static void imx_gpt_set_freq(IMXGPTState *s)
 {
 uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
@@ -512,6 +523,13 @@ static void imx6_gpt_init(Object *obj)
 s->clocks = imx6_gpt_clocks;
 }
 
+static void imx7_gpt_init(Object *obj)
+{
+IMXGPTState *s = IMX_GPT(obj);
+
+s->clocks = imx7_gpt_clocks;
+}
+
 static const TypeInfo imx25_gpt_info = {
 .name = TYPE_IMX25_GPT,
 .parent = TYPE_SYS_BUS_DEVICE,
@@ -532,11 +550,18 @@ static const TypeInfo imx6_gpt_info = {
 .instance_init = imx6_gpt_init,
 };
 
+static const TypeInfo imx7_gpt_info = {
+.name = TYPE_IMX7_GPT,
+.parent = TYPE_IMX25_GPT,
+.instance_init = imx7_gpt_init,
+};
+
 static void imx_gpt_register_types(void)
 {
 type_register_static(_gpt_info);
 type_register_static(_gpt_info);
 type_register_static(_gpt_info);
+type_register_static(_gpt_info);
 }
 
 type_init(imx_gpt_register_types)
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
index eac59b2a70..20ccb327c4 100644
--- a/include/hw/timer/imx_gpt.h
+++ b/include/hw/timer/imx_gpt.h
@@ -77,6 +77,7 @@
 #define TYPE_IMX25_GPT "imx25.gpt"
 #define TYPE_IMX31_GPT "imx31.gpt"
 #define TYPE_IMX6_GPT "imx6.gpt"
+#define TYPE_IMX7_GPT "imx7.gpt"
 
 #define TYPE_IMX_GPT TYPE_IMX25_GPT
 
-- 
2.14.3




[Qemu-devel] [PATCH v5 13/14] hw/arm: Move virt's PSCI DT fixup code to arm/boot.c

2018-02-06 Thread Andrey Smirnov
Move virt's PSCI DT fixup code to arm/boot.c and set this fixup to
happen automatically for every board that doesn't mark "psci-conduit"
as disabled. This way emulated boards other than "virt" that rely on
PSIC for SMP could benefit from that code.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/arm/boot.c | 65 +++
 hw/arm/virt.c | 61 ---
 2 files changed, 65 insertions(+), 61 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index c2720c8046..18ada9152c 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -384,6 +384,69 @@ static void set_kernel_args_old(const struct arm_boot_info 
*info)
 }
 }
 
+static void fdt_add_psci_node(void *fdt)
+{
+uint32_t cpu_suspend_fn;
+uint32_t cpu_off_fn;
+uint32_t cpu_on_fn;
+uint32_t migrate_fn;
+ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
+const char *psci_method;
+int64_t psci_conduit;
+
+psci_conduit = object_property_get_int(OBJECT(armcpu),
+   "psci-conduit",
+   _abort);
+switch (psci_conduit) {
+case QEMU_PSCI_CONDUIT_DISABLED:
+return;
+case QEMU_PSCI_CONDUIT_HVC:
+psci_method = "hvc";
+break;
+case QEMU_PSCI_CONDUIT_SMC:
+psci_method = "smc";
+break;
+default:
+g_assert_not_reached();
+}
+
+qemu_fdt_add_subnode(fdt, "/psci");
+if (armcpu->psci_version == 2) {
+const char comp[] = "arm,psci-0.2\0arm,psci";
+qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
+
+cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
+if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
+cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
+cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
+migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
+} else {
+cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
+cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
+migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
+}
+} else {
+qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
+
+cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
+cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
+cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
+migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
+}
+
+/* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
+ * to the instruction that should be used to invoke PSCI functions.
+ * However, the device tree binding uses 'method' instead, so that is
+ * what we should use here.
+ */
+qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
+
+qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
+qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
+qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
+qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
+}
+
 /**
  * load_dtb() - load a device tree binary image into memory
  * @addr:   the address to load the image at
@@ -540,6 +603,8 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
 }
 }
 
+fdt_add_psci_node(fdt);
+
 if (binfo->modify_dtb) {
 binfo->modify_dtb(binfo, fdt);
 }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b334c82eda..dbb3c8036a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -244,66 +244,6 @@ static void create_fdt(VirtMachineState *vms)
 }
 }
 
-static void fdt_add_psci_node(const VirtMachineState *vms)
-{
-uint32_t cpu_suspend_fn;
-uint32_t cpu_off_fn;
-uint32_t cpu_on_fn;
-uint32_t migrate_fn;
-void *fdt = vms->fdt;
-ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
-const char *psci_method;
-
-switch (vms->psci_conduit) {
-case QEMU_PSCI_CONDUIT_DISABLED:
-return;
-case QEMU_PSCI_CONDUIT_HVC:
-psci_method = "hvc";
-break;
-case QEMU_PSCI_CONDUIT_SMC:
-psci_method = "smc";
-break;
-default:
-g_assert_not_reached();
-}
-
-qemu_fdt_add_subnode(fdt, "/psci");
-if (armcpu->psci_version == 2) {
-const char comp[] = "arm,psci-0.2\0arm,psci";
-qemu_fdt_setprop(fdt, "/ps

[Qemu-devel] [PATCH v5 06/14] i.MX: Add code to emulate GPCv2 IP block

2018-02-06 Thread Andrey Smirnov
Add minimal code needed to allow upstream Linux guest to boot.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/intc/Makefile.objs   |   2 +-
 hw/intc/imx_gpcv2.c | 125 
 include/hw/intc/imx_gpcv2.h |  22 
 3 files changed, 148 insertions(+), 1 deletion(-)
 create mode 100644 hw/intc/imx_gpcv2.c
 create mode 100644 include/hw/intc/imx_gpcv2.h

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 571e094a14..0e9963f5ee 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -6,7 +6,7 @@ common-obj-$(CONFIG_XILINX) += xilinx_intc.o
 common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-pmu-iomod-intc.o
 common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-ipi.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o
-common-obj-$(CONFIG_IMX) += imx_avic.o
+common-obj-$(CONFIG_IMX) += imx_avic.o imx_gpcv2.o
 common-obj-$(CONFIG_LM32) += lm32_pic.o
 common-obj-$(CONFIG_REALVIEW) += realview_gic.o
 common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c
new file mode 100644
index 00..4eb9ce2668
--- /dev/null
+++ b/hw/intc/imx_gpcv2.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 GPCv2 block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/intc/imx_gpcv2.h"
+#include "qemu/log.h"
+
+#define GPC_PU_PGC_SW_PUP_REQ   0x0f8
+#define GPC_PU_PGC_SW_PDN_REQ   0x104
+
+#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
+#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
+#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
+#define PCIE_PHY_SW_Pxx_REQ BIT(1)
+#define MIPI_PHY_SW_Pxx_REQ BIT(0)
+
+
+static void imx_gpcv2_reset(DeviceState *dev)
+{
+IMXGPCv2State *s = IMX_GPCV2(dev);
+
+memset(s->regs, 0, sizeof(s->regs));
+}
+
+static uint64_t imx_gpcv2_read(void *opaque, hwaddr offset,
+   unsigned size)
+{
+IMXGPCv2State *s = opaque;
+
+return s->regs[offset / sizeof(uint32_t)];
+}
+
+static void imx_gpcv2_write(void *opaque, hwaddr offset,
+uint64_t value, unsigned size)
+{
+IMXGPCv2State *s = opaque;
+const size_t idx = offset / sizeof(uint32_t);
+
+s->regs[idx] = value;
+
+/*
+ * Real HW will clear those bits once as a way to indicate that
+ * power up request is complete
+ */
+if (offset == GPC_PU_PGC_SW_PUP_REQ ||
+offset == GPC_PU_PGC_SW_PDN_REQ) {
+s->regs[idx] &= ~(USB_HSIC_PHY_SW_Pxx_REQ |
+  USB_OTG2_PHY_SW_Pxx_REQ |
+  USB_OTG1_PHY_SW_Pxx_REQ |
+  PCIE_PHY_SW_Pxx_REQ |
+  MIPI_PHY_SW_Pxx_REQ);
+}
+}
+
+static const struct MemoryRegionOps imx_gpcv2_ops = {
+.read = imx_gpcv2_read,
+.write = imx_gpcv2_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void imx_gpcv2_init(Object *obj)
+{
+SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+IMXGPCv2State *s = IMX_GPCV2(obj);
+
+memory_region_init_io(>iomem,
+  obj,
+  _gpcv2_ops,
+  s,
+  TYPE_IMX_GPCV2 ".iomem",
+  sizeof(s->regs));
+sysbus_init_mmio(sd, >iomem);
+}
+
+static const VMStateDescription vmstate_imx_gpcv2 = {
+.name = TYPE_IMX_GPCV2,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMXGPCv2State, GPC_NUM),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void imx_gpcv2_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->reset = imx_gpcv2_reset;
+dc->vmsd  = _imx_gpcv2;
+dc->desc  = "i.MX GPCv2 Module";
+}
+
+static const TypeInfo imx_gpcv2_info = {
+.name  = TYPE_IMX_GPCV2,
+.parent= TYPE_SYS_BUS_DEVICE,
+.inst

[Qemu-devel] [PATCH v5 11/14] usb: Add basic code to emulate Chipidea USB IP

2018-02-06 Thread Andrey Smirnov
Add code to emulate Chipidea USB IP (used in i.MX SoCs). Tested to
work against:

-usb -drive if=none,id=stick,file=usb.img,format=raw -device \
 usb-storage,bus=usb-bus.0,drive=stick

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/usb/Makefile.objs  |   1 +
 hw/usb/chipidea.c | 176 ++
 include/hw/usb/chipidea.h |  16 +
 3 files changed, 193 insertions(+)
 create mode 100644 hw/usb/chipidea.c
 create mode 100644 include/hw/usb/chipidea.h

diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index fbcd498c59..41be700812 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -12,6 +12,7 @@ common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o
 common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
 
 obj-$(CONFIG_TUSB6010) += tusb6010.o
+obj-$(CONFIG_IMX)  += chipidea.o
 
 # emulated usb devices
 common-obj-$(CONFIG_USB) += dev-hub.o
diff --git a/hw/usb/chipidea.c b/hw/usb/chipidea.c
new file mode 100644
index 00..60d67f88b8
--- /dev/null
+++ b/hw/usb/chipidea.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * Chipidea USB block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/usb/hcd-ehci.h"
+#include "hw/usb/chipidea.h"
+#include "qemu/log.h"
+
+enum {
+CHIPIDEA_USBx_DCIVERSION   = 0x000,
+CHIPIDEA_USBx_DCCPARAMS= 0x004,
+CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
+};
+
+static uint64_t chipidea_read(void *opaque, hwaddr offset,
+   unsigned size)
+{
+return 0;
+}
+
+static void chipidea_write(void *opaque, hwaddr offset,
+uint64_t value, unsigned size)
+{
+}
+
+static const struct MemoryRegionOps chipidea_ops = {
+.read = chipidea_read,
+.write = chipidea_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the
+ * real device but in practice there is no reason for a guest
+ * to access this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+switch (offset) {
+case CHIPIDEA_USBx_DCIVERSION:
+return 0x1;
+case CHIPIDEA_USBx_DCCPARAMS:
+/*
+ * Real hardware (at least i.MX7) will also report the
+ * controller as "Device Capable" (and 8 supported endpoints),
+ * but there doesn't seem to be much point in doing so, since
+ * we don't emulate that part.
+ */
+return CHIPIDEA_USBx_DCCPARAMS_HC;
+}
+
+return 0;
+}
+
+static void chipidea_dc_write(void *opaque, hwaddr offset,
+  uint64_t value, unsigned size)
+{
+}
+
+static const struct MemoryRegionOps chipidea_dc_ops = {
+.read = chipidea_dc_read,
+.write = chipidea_dc_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void chipidea_init(Object *obj)
+{
+EHCIState *ehci = _BUS_EHCI(obj)->ehci;
+ChipideaState *ci = CHIPIDEA(obj);
+int i;
+
+for (i = 0; i < ARRAY_SIZE(ci->iomem); i++) {
+const struct {
+const char *name;
+hwaddr offset;
+uint64_t size;
+const struct MemoryRegionOps *ops;
+} regions[ARRAY_SIZE(ci->iomem)] = {
+/*
+ * Registers located between offsets 0x000 and 0xFC
+ */
+{
+.name   = TYPE_CHIPIDEA ".misc",
+.offset = 0x000,
+.size   = 0x100,
+.ops= _ops,
+},
+/*
+ * Registers located between offsets 0x1A4 and 0x1DC
+ */
+{
+.name   = TYPE_CHIPIDEA "

[Qemu-devel] [PATCH v5 05/14] i.MX: Add code to emulate i.MX7 SNVS IP-block

2018-02-06 Thread Andrey Smirnov
Add code to emulate SNVS IP-block. Currently only the bits needed to
be able to emulate machine shutdown are implemented.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/misc/Makefile.objs   |  1 +
 hw/misc/imx7_snvs.c | 83 +
 include/hw/misc/imx7_snvs.h | 35 +++
 3 files changed, 119 insertions(+)
 create mode 100644 hw/misc/imx7_snvs.c
 create mode 100644 include/hw/misc/imx7_snvs.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4b2b705a6c..019886912c 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -35,6 +35,7 @@ obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_IMX) += imx2_wdt.o
+obj-$(CONFIG_IMX) += imx7_snvs.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx7_snvs.c b/hw/misc/imx7_snvs.c
new file mode 100644
index 00..4df482b282
--- /dev/null
+++ b/hw/misc/imx7_snvs.c
@@ -0,0 +1,83 @@
+/*
+ * IMX7 Secure Non-Volatile Storage
+ *
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Bare minimum emulation code needed to support being able to shut
+ * down linux guest gracefully.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx7_snvs.h"
+#include "qemu/log.h"
+#include "sysemu/sysemu.h"
+
+static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
+{
+return 0;
+}
+
+static void imx7_snvs_write(void *opaque, hwaddr offset,
+uint64_t v, unsigned size)
+{
+const uint32_t value = v;
+const uint32_t mask  = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
+
+if (offset == SNVS_LPCR && ((value & mask) == mask)) {
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+}
+}
+
+static const struct MemoryRegionOps imx7_snvs_ops = {
+.read = imx7_snvs_read,
+.write = imx7_snvs_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void imx7_snvs_init(Object *obj)
+{
+SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+IMX7SNVSState *s = IMX7_SNVS(obj);
+
+memory_region_init_io(>mmio, obj, _snvs_ops, s,
+  TYPE_IMX7_SNVS, 0x1000);
+
+sysbus_init_mmio(sd, >mmio);
+}
+
+static void imx7_snvs_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc  = "i.MX7 Secure Non-Volatile Storage Module";
+}
+
+static const TypeInfo imx7_snvs_info = {
+.name  = TYPE_IMX7_SNVS,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(IMX7SNVSState),
+.instance_init = imx7_snvs_init,
+.class_init= imx7_snvs_class_init,
+};
+
+static void imx7_snvs_register_type(void)
+{
+type_register_static(_snvs_info);
+}
+type_init(imx7_snvs_register_type)
diff --git a/include/hw/misc/imx7_snvs.h b/include/hw/misc/imx7_snvs.h
new file mode 100644
index 00..255f8f26f9
--- /dev/null
+++ b/include/hw/misc/imx7_snvs.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 SNVS block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef IMX7_SNVS_H
+#define IMX7_SNVS_H
+
+#include "qemu/bitops.h"
+#include "hw/sysbus.h"
+
+
+enum IMX7SNVSRegisters {
+SNVS_LPCR = 0x38,
+SNVS_LPCR_TOP   = BIT(6),
+SNVS_LPCR_DP_EN = BIT(5)
+};
+
+#define TYPE_IMX7_SNVS "imx7.snvs"
+#define IMX7_SNVS(obj) OBJECT_CHECK(IMX7SNVSState, (obj), TYPE_IMX7_SNVS)
+
+typedef struct IMX7SNVSState {
+/*  */
+SysBusDevice parent_obj;
+
+MemoryRegion mmio;
+} IMX7SNVSState;
+
+#endif /* IMX7_SNVS_H */
-- 
2.14.3




[Qemu-devel] [PATCH v5 01/14] sdhci: Add i.MX specific subtype of SDHCI

2018-02-06 Thread Andrey Smirnov
IP block found on several generations of i.MX family does not use
vanilla SDHCI implementation and it comes with a number of quirks.

Introduce i.MX SDHCI subtype of SDHCI block to add code necessary to
support unmodified Linux guest driver.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/sd/sdhci-internal.h |  20 +
 hw/sd/sdhci.c  | 230 -
 include/hw/sd/sdhci.h  |  13 +++
 3 files changed, 262 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index fc807f08f3..f91b73af59 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -84,12 +84,18 @@
 
 /* R/W Host control Register 0x0 */
 #define SDHC_HOSTCTL   0x28
+#define SDHC_CTRL_LED  0x01
 #define SDHC_CTRL_DMA_CHECK_MASK   0x18
 #define SDHC_CTRL_SDMA 0x00
 #define SDHC_CTRL_ADMA1_32 0x08
 #define SDHC_CTRL_ADMA2_32 0x10
 #define SDHC_CTRL_ADMA2_64 0x18
 #define SDHC_DMA_TYPE(x)   ((x) & SDHC_CTRL_DMA_CHECK_MASK)
+#define SDHC_CTRL_4BITBUS  0x02
+#define SDHC_CTRL_8BITBUS  0x20
+#define SDHC_CTRL_CDTEST_INS   0x40
+#define SDHC_CTRL_CDTEST_EN0x80
+
 
 /* R/W Power Control Register 0x0 */
 #define SDHC_PWRCON0x29
@@ -226,4 +232,18 @@ enum {
 sdhc_gap_write  = 2   /* SDHC stopped at block gap during write operation 
*/
 };
 
+extern const VMStateDescription sdhci_vmstate;
+
+
+#define ESDHC_MIX_CTRL  0x48
+#define ESDHC_VENDOR_SPEC   0xc0
+#define ESDHC_DLL_CTRL  0x60
+
+#define ESDHC_TUNING_CTRL   0xcc
+#define ESDHC_TUNE_CTRL_STATUS  0x68
+#define ESDHC_WTMK_LVL  0x44
+
+#define ESDHC_CTRL_4BITBUS  (0x1 << 1)
+#define ESDHC_CTRL_8BITBUS  (0x2 << 1)
+
 #endif
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index fac7fa5c72..7c9683b47d 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -244,7 +244,8 @@ static void sdhci_send_command(SDHCIState *s)
 }
 }
 
-if ((s->norintstsen & SDHC_NISEN_TRSCMP) &&
+if (!(s->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
+(s->norintstsen & SDHC_NISEN_TRSCMP) &&
 (s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
 s->norintsts |= SDHC_NIS_TRSCMP;
 }
@@ -1189,6 +1190,8 @@ static void sdhci_initfn(SDHCIState *s)
 
 s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
sdhci_raise_insertion_irq, s);
 s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, 
s);
+
+s->io_ops = _mmio_ops;
 }
 
 static void sdhci_uninitfn(SDHCIState *s)
@@ -1396,6 +1399,10 @@ static void sdhci_sysbus_realize(DeviceState *dev, Error 
** errp)
 }
 
 sysbus_init_irq(sbd, >irq);
+
+memory_region_init_io(>iomem, OBJECT(s), s->io_ops, s, "sdhci",
+SDHC_REGISTERS_MAP_SIZE);
+
 sysbus_init_mmio(sbd, >iomem);
 }
 
@@ -1447,11 +1454,232 @@ static const TypeInfo sdhci_bus_info = {
 .class_init = sdhci_bus_class_init,
 };
 
+static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
+{
+SDHCIState *s = SYSBUS_SDHCI(opaque);
+uint32_t ret;
+uint16_t hostctl;
+
+switch (offset) {
+default:
+return sdhci_read(opaque, offset, size);
+
+case SDHC_HOSTCTL:
+/*
+ * For a detailed explanation on the following bit
+ * manipulation code see comments in a similar part of
+ * usdhc_write()
+ */
+hostctl = SDHC_DMA_TYPE(s->hostctl) << (8 - 3);
+
+if (s->hostctl & SDHC_CTRL_8BITBUS) {
+hostctl |= ESDHC_CTRL_8BITBUS;
+}
+
+if (s->hostctl & SDHC_CTRL_4BITBUS) {
+hostctl |= ESDHC_CTRL_4BITBUS;
+}
+
+ret  = hostctl;
+ret |= (uint32_t)s->blkgap << 16;
+ret |= (uint32_t)s->wakcon << 24;
+
+break;
+
+case ESDHC_DLL_CTRL:
+case ESDHC_TUNE_CTRL_STATUS:
+case 0x6c:
+case ESDHC_TUNING_CTRL:
+case ESDHC_VENDOR_SPEC:
+case ESDHC_MIX_CTRL:
+case ESDHC_WTMK_LVL:
+ret = 0;
+break;
+}
+
+return ret;
+}
+
+static void
+usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
+{
+SDHCIState *s = SYSBUS_SDHCI(opaque);
+uint8_t hostctl;
+uint32_t value = (uint32_t)val;
+
+switch 

[Qemu-devel] [PATCH v5 04/14] i.MX: Add code to emulate i.MX2 watchdog IP block

2018-02-06 Thread Andrey Smirnov
Add enough code to emulate i.MX2 watchdog IP block so it would be
possible to reboot the machine running Linux Guest.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/misc/Makefile.objs  |  1 +
 hw/misc/imx2_wdt.c | 89 ++
 include/hw/misc/imx2_wdt.h | 33 +
 3 files changed, 123 insertions(+)
 create mode 100644 hw/misc/imx2_wdt.c
 create mode 100644 include/hw/misc/imx2_wdt.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a28e5e49b0..4b2b705a6c 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -34,6 +34,7 @@ obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
+obj-$(CONFIG_IMX) += imx2_wdt.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c
new file mode 100644
index 00..e47e442592
--- /dev/null
+++ b/hw/misc/imx2_wdt.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX2 Watchdog IP block
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "sysemu/watchdog.h"
+
+#include "hw/misc/imx2_wdt.h"
+
+#define IMX2_WDT_WCR_WDABIT(5)  /* -> External Reset WDOG_B */
+#define IMX2_WDT_WCR_SRSBIT(4)  /* -> Software Reset Signal */
+
+static uint64_t imx2_wdt_read(void *opaque, hwaddr addr,
+  unsigned int size)
+{
+return 0;
+}
+
+static void imx2_wdt_write(void *opaque, hwaddr addr,
+   uint64_t value, unsigned int size)
+{
+if (addr == IMX2_WDT_WCR &&
+(value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
+watchdog_perform_action();
+}
+}
+
+static const MemoryRegionOps imx2_wdt_ops = {
+.read  = imx2_wdt_read,
+.write = imx2_wdt_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the
+ * real device but in practice there is no reason for a guest
+ * to access this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void imx2_wdt_realize(DeviceState *dev, Error **errp)
+{
+IMX2WdtState *s = IMX2_WDT(dev);
+
+memory_region_init_io(>mmio, OBJECT(dev),
+  _wdt_ops, s,
+  TYPE_IMX2_WDT".mmio",
+  IMX2_WDT_REG_NUM * sizeof(uint16_t));
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
+}
+
+static void imx2_wdt_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = imx2_wdt_realize;
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static const TypeInfo imx2_wdt_info = {
+.name  = TYPE_IMX2_WDT,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(IMX2WdtState),
+.class_init= imx2_wdt_class_init,
+};
+
+static WatchdogTimerModel model = {
+.wdt_name = "imx2-watchdog",
+.wdt_description = "i.MX2 Watchdog",
+};
+
+static void imx2_wdt_register_type(void)
+{
+watchdog_add_model();
+type_register_static(_wdt_info);
+}
+type_init(imx2_wdt_register_type)
diff --git a/include/hw/misc/imx2_wdt.h b/include/hw/misc/imx2_wdt.h
new file mode 100644
index 00..8afc99a10e
--- /dev/null
+++ b/include/hw/misc/imx2_wdt.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX2 Watchdog IP block
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef IMX2_WDT_H
+#define IMX2_WDT_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_IMX2_WDT "imx2.wdt"
+#define IMX2_WDT(obj) OBJECT_CHECK(IMX2WdtState, (obj), TYPE_IMX2_WDT)
+
+enum IMX2WdtRegisters {
+IMX2_WDT_WCR = 0x,
+IMX2_WDT_REG_NUM = 0x0008 / sizeof(uint16_t) + 1,
+};
+
+
+typedef struct IMX2WdtState {
+/*  */
+SysBusDevice parent_obj;
+
+MemoryRegion mmio;
+} IMX2WdtState;
+
+#endif /* IMX7_SNVS_H */
-- 
2.14.3




[Qemu-devel] [PATCH v5 02/14] hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC

2018-02-06 Thread Andrey Smirnov
Convert i.MX6 to use TYPE_IMX_USDHC since that's what real HW comes
with.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/arm/fsl-imx6.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index b0d4088290..e6559a8b12 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -93,7 +93,7 @@ static void fsl_imx6_init(Object *obj)
 }
 
 for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
-object_initialize(>esdhc[i], sizeof(s->esdhc[i]), 
TYPE_SYSBUS_SDHCI);
+object_initialize(>esdhc[i], sizeof(s->esdhc[i]), TYPE_IMX_USDHC);
 qdev_set_parent_bus(DEVICE(>esdhc[i]), sysbus_get_default());
 snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
 object_property_add_child(obj, name, OBJECT(>esdhc[i]), NULL);
-- 
2.14.3




[Qemu-devel] [PATCH v5 03/14] i.MX: Add code to emulate i.MX7 CCM, PMU and ANALOG IP blocks

2018-02-06 Thread Andrey Smirnov
Add minimal code needed to allow upstream Linux guest to boot.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: Marcel Apfelbaum <marcel.apfelb...@zoho.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx7_ccm.c | 277 +
 include/hw/misc/imx7_ccm.h | 139 +++
 3 files changed, 417 insertions(+)
 create mode 100644 hw/misc/imx7_ccm.c
 create mode 100644 include/hw/misc/imx7_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d517f83e81..a28e5e49b0 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -33,6 +33,7 @@ obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
+obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
new file mode 100644
index 00..d90c48bfec
--- /dev/null
+++ b/hw/misc/imx7_ccm.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+
+#include "hw/misc/imx7_ccm.h"
+
+static void imx7_analog_reset(DeviceState *dev)
+{
+IMX7AnalogState *s = IMX7_ANALOG(dev);
+
+memset(s->pmu, 0, sizeof(s->pmu));
+memset(s->analog, 0, sizeof(s->analog));
+
+s->analog[ANALOG_PLL_ARM] = 0x2042;
+s->analog[ANALOG_PLL_DDR] = 0x0060302c;
+s->analog[ANALOG_PLL_DDR_SS]  = 0x;
+s->analog[ANALOG_PLL_DDR_NUM] = 0x06aaac4d;
+s->analog[ANALOG_PLL_DDR_DENOM]   = 0x13ec;
+s->analog[ANALOG_PLL_480] = 0x2000;
+s->analog[ANALOG_PLL_480A]= 0x52605a56;
+s->analog[ANALOG_PLL_480B]= 0x52525216;
+s->analog[ANALOG_PLL_ENET]= 0x1fc0;
+s->analog[ANALOG_PLL_AUDIO]   = 0x0001301b;
+s->analog[ANALOG_PLL_AUDIO_SS]= 0x;
+s->analog[ANALOG_PLL_AUDIO_NUM]   = 0x05f5e100;
+s->analog[ANALOG_PLL_AUDIO_DENOM] = 0x2964619c;
+s->analog[ANALOG_PLL_VIDEO]   = 0x0008201b;
+s->analog[ANALOG_PLL_VIDEO_SS]= 0x;
+s->analog[ANALOG_PLL_VIDEO_NUM]   = 0xf699;
+s->analog[ANALOG_PLL_VIDEO_DENOM] = 0x000f4240;
+s->analog[ANALOG_PLL_MISC0]   = 0x;
+
+/* all PLLs need to be locked */
+s->analog[ANALOG_PLL_ARM]   |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_DDR]   |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_480]   |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_480A]  |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_480B]  |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_ENET]  |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_AUDIO] |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_VIDEO] |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_MISC0] |= ANALOG_PLL_LOCK;
+
+/*
+ * Since I couldn't find any info about this in the reference
+ * manual the value of this register is based strictly on matching
+ * what Linux kernel expects it to be.
+ */
+s->analog[ANALOG_DIGPROG]  = 0x72;
+/*
+ * Set revision to be 1.0 (Arbitrary choice, no particular
+ * reason).
+ */
+s->analog[ANALOG_DIGPROG] |= 0x10;
+}
+
+static void imx7_ccm_reset(DeviceState *dev)
+{
+IMX7CCMState *s = IMX7_CCM(dev);
+
+memset(s->ccm, 0, sizeof(s->ccm));
+}
+
+#define CCM_INDEX(offset)   (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
+#define CCM_BITOP(offset)   ((offset) & (hwaddr)0xF)
+
+enum {
+CCM_BITOP_NONE = 0x00,
+CCM_BITOP_SET  = 0x04,
+CCM_BITOP_CLR  = 0x08,
+CCM_BITOP_TOG  = 0x0C,
+};
+
+static uint64_t imx7_set_clr_tog_read(void *opaque, hwaddr offset,
+  unsigned size)
+{
+const uint32_t *mmio = opaque;
+
+return mmio[CCM_INDEX(offset)];
+}
+
+static void imx7_set_clr_tog_write(void *opaque, hwaddr offset,
+   uint64_t value, unsigned size)
+{
+const uint8_t  bitop = CCM_BITOP(offset);
+const uint32_t index = CCM_INDEX(offset);
+uint32_t *mmio = opaque;
+
+switch (bitop) {
+case CCM_BITOP_NONE:
+mmio[index]  = value;
+break;
+case CCM_BITOP_SET:

[Qemu-devel] [PATCH v5 00/14] Initial i.MX7 support

2018-02-06 Thread Andrey Smirnov
Hi everyone,

This v5 of the patch series containing the work that I've done in
order to enable support for i.MX7 emulation in QEMU.

As the one before last commit in the series states the supported i.MX7
features are:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller
* 3 USB controllers
* 1 LCD controller
* 1 ARMv7 DAP IP block

Feedback is welcome!

Changes since [v4]:

- Rebase patchest on top of latest QEMU master

- Reworked PCIE emulation code to create MemoryRegions
  only once

- Fixed incorrect usages of PCI instead of PCIE

- Fixed device class reported by PCIE bridge

- Added patch to make pci_data_read() and pci_data_write() usable
  for PCIE devices as well

- Converted PCIE code to use pci_data_read() and pci_data_write()

- Added VMStateDescription code for PCIE

- Collected Reviewed-by tag from Philippe

Changes since [v3]:

- Changes to FEC were split into a separate set and merged to master

- Patchest is rebased on latest master

- Converted to use PSCI DT fixup code that is shared with virt
  platform (now relocated to live in arm/boot.c)

- Large number of dummy block were converted to use
  create_unimplemented_device() as opposed to its own dedicated
  type

- Incorporated varios small feedback items

- Collected Reviewed-by tags from Peter

Changes since [v2]:

- Added stubs for more blocks that were causing memory
  transactions when booting Linux guest as were revealed by
  additional testing of the patchest

- Added proper USB emulation code, so now it should be possible to
  emulated guest's USB bus

Changes since [v1]:

- Patchset no longer relies on "ignore_memory_transaction_failures = false"
  for its functionality

- As a consequnce of implementing the above a number of patches
  implementing dummy IP block emulation as well as PCIe emulation
  patches that I alluded to in [v1] are now included in this patch
  series

- "has_el3" property is no longer being set to "false" as a part
  of intialization of A7 CPU. I couldn't reproduce the issues that
  I thought I was having, so I just dropped that code.

- A number of smaller feedback items from Peter and other has been
  incorporated into the patches.


Thanks,
Andrey Smirnov

[v4] https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg03264.html
[v3] https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg04236.html
[v2] https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05516.html
[v1] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg04770.html

Andrey Smirnov (14):
  sdhci: Add i.MX specific subtype of SDHCI
  hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC
  i.MX: Add code to emulate i.MX7 CCM, PMU and ANALOG IP blocks
  i.MX: Add code to emulate i.MX2 watchdog IP block
  i.MX: Add code to emulate i.MX7 SNVS IP-block
  i.MX: Add code to emulate GPCv2 IP block
  i.MX: Add i.MX7 GPT variant
  i.MX: Add implementation of i.MX7 GPR IP block
  pci: Use pci_config_size in pci_data_* accessors
  pci: Add support for Designware IP block
  usb: Add basic code to emulate Chipidea USB IP
  i.MX: Add i.MX7 SOC implementation.
  hw/arm: Move virt's PSCI DT fixup code to arm/boot.c
  Implement support for i.MX7 Sabre board

 default-configs/arm-softmmu.mak  |   3 +
 hw/arm/Makefile.objs |   3 +
 hw/arm/boot.c|  65 
 hw/arm/fsl-imx6.c|   2 +-
 hw/arm/fsl-imx7.c| 580 ++
 hw/arm/mcimx7d-sabre.c   |  90 +
 hw/arm/virt.c|  61 
 hw/intc/Makefile.objs|   2 +-
 hw/intc/imx_gpcv2.c  | 125 +++
 hw/misc/Makefile.objs|   4 +
 hw/misc/imx2_wdt.c   |  89 +
 hw/misc/imx7_ccm.c   | 277 ++
 hw/misc/imx7_gpr.c   | 124 +++
 hw/misc/imx7_snvs.c  |  83 +
 hw/misc/trace-events |   4 +
 hw/pci-host/Makefile.objs|   2 +
 hw/pci-host/designware.c | 759 +++
 hw/pci/pci_host.c|  13 +-
 hw/sd/sdhci-internal.h   |  20 ++
 hw/sd/sdhci.c| 230 +++-
 hw/timer/imx_gpt.c   |  25 ++
 hw/usb/Makefile.objs |   1 +
 hw/usb/chipidea.c| 176 +
 include/hw/arm/fsl-imx7.h| 221

Re: [Qemu-devel] [PATCH v4 09/14] pci: Add support for Designware IP block

2018-02-06 Thread Andrey Smirnov
On Wed, Jan 31, 2018 at 4:13 AM, Marcel Apfelbaum <mar...@redhat.com> wrote:
> On 30/01/2018 19:49, Andrey Smirnov wrote:
>> On Tue, Jan 30, 2018 at 5:18 AM, Marcel Apfelbaum
>> <marcel.apfelb...@zoho.com> wrote:
>>> Hi Andrei,
>>>
>>> Sorry for letting you wait,
>>> I have some comments/questions below.
>>>
>>>
>>> On 16/01/2018 3:37, Andrey Smirnov wrote:
>>>>
>>>> Add code needed to get a functional PCI subsytem when using in
>>>> conjunction with upstream Linux guest (4.13+). Tested to work against
>>>> "e1000e" (network adapter, using MSI interrupts) as well as
>>>> "usb-ehci" (USB controller, using legacy PCI interrupts).
>>>>
>>>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>>>> Cc: Jason Wang <jasow...@redhat.com>
>>>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>>>> Cc: qemu-devel@nongnu.org
>>>> Cc: qemu-...@nongnu.org
>>>> Cc: yurov...@gmail.com
>>>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>>>> ---
>>>>   default-configs/arm-softmmu.mak  |   2 +
>>>>   hw/pci-host/Makefile.objs|   2 +
>>>>   hw/pci-host/designware.c | 618
>>>> +++
>>>>   include/hw/pci-host/designware.h |  93 ++
>>>>   include/hw/pci/pci_ids.h |   2 +
>>>>   5 files changed, 717 insertions(+)
>>>>   create mode 100644 hw/pci-host/designware.c
>>>>   create mode 100644 include/hw/pci-host/designware.h
>>>>
>>>> diff --git a/default-configs/arm-softmmu.mak
>>>> b/default-configs/arm-softmmu.mak
>>>> index b0d6e65038..0c5ae914ed 100644
>>>> --- a/default-configs/arm-softmmu.mak
>>>> +++ b/default-configs/arm-softmmu.mak
>>>> @@ -132,3 +132,5 @@ CONFIG_GPIO_KEY=y
>>>>   CONFIG_MSF2=y
>>>>   CONFIG_FW_CFG_DMA=y
>>>>   CONFIG_XILINX_AXI=y
>>>> +CONFIG_PCI_DESIGNWARE=y
>>>> +
>>>> diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
>>>> index 9c7909cf44..0e2c0a123b 100644
>>>> --- a/hw/pci-host/Makefile.objs
>>>> +++ b/hw/pci-host/Makefile.objs
>>>> @@ -17,3 +17,5 @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
>>>>   common-obj-$(CONFIG_PCI_Q35) += q35.o
>>>>   common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
>>>>   common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
>>>> +
>>>> +common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
>>>> diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
>>>> new file mode 100644
>>>> index 00..98fff5e5f3
>>>> --- /dev/null
>>>> +++ b/hw/pci-host/designware.c
>>>> @@ -0,0 +1,618 @@
>>>> +/*
>>>> + * Copyright (c) 2017, Impinj, Inc.
>>>
>>> 2018 :)
>>>
>>>> + *
>>>> + * Designware PCIe IP block emulation
>>>> + *
>>>> + * This library is free software; you can redistribute it and/or
>>>> + * modify it under the terms of the GNU Lesser General Public
>>>> + * License as published by the Free Software Foundation; either
>>>> + * version 2 of the License, or (at your option) any later version.
>>>> + *
>>>> + * This library is distributed in the hope that it will be useful,
>>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>>> + * Lesser General Public License for more details.
>>>> + *
>>>> + * You should have received a copy of the GNU Lesser General Public
>>>> + * License along with this library; if not, see
>>>> + * <http://www.gnu.org/licenses/>.
>>>> + */
>>>> +
>>>> +#include "qemu/osdep.h"
>>>> +#include "qapi/error.h"
>>>> +#include "hw/pci/msi.h"
>>>> +#include "hw/pci/pci_bridge.h"
>>>> +#include "hw/pci/pci_host.h"
>>>> +#include "hw/pci/pcie_port.h"
>>>> +#include "hw/pci-host/designware.h"
>>>> +
>>>> +#define PCIE_PORT_LINK_CONTROL  0x710
>>>> +
>>>> +#define PCIE_PHY_DEBUG_R1   0x72C
>>>> +#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP  BIT(4)
>>>> +

Re: [Qemu-devel] [PATCH v4 00/14] Initial i.MX7 support

2018-02-06 Thread Andrey Smirnov
On Wed, Jan 31, 2018 at 9:03 AM, Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> Hi Peter, Andrey.
>
> On 01/15/2018 10:36 PM, Andrey Smirnov wrote:
>> Hi everyone,
>>
>> This v4 of the patch series containing the work that I've done in
>> order to enable support for i.MX7 emulation in QEMU.
>>
>> *NOTE*: Patches 1 and 2 are provided for the sake of completness and
>>   are going to have to be adapted once Philippe's SD changes
>>   land in master. As such, they are NOT ready to be
>>   accepted/merged.
>
> Peter:
> Since my series are taking longer, if this series is ready it is
> probably easier to apply Andrey series first and I'll adapt my SDHCI
> series after.
>
> Andrey:
> I only plan to keep the sdhci.c file generic (dealing with quirks) and
> split out the imx usdhci code, similar to this patch:
> https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg01265.html

Yes, I understand that, but I still am not clear how you propose
dealing with the fact that i.MX specific read/write functions need to
call similar functions from parent SDHC class. Are you planning on
adding overridable read()/write() methods to SDHCICommonClass?

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v4 05/14] i.MX: Add code to emulate i.MX7 SNVS IP-block

2018-02-06 Thread Andrey Smirnov
On Wed, Jan 31, 2018 at 9:10 AM, Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> On 01/15/2018 10:37 PM, Andrey Smirnov wrote:
>> Add code to emulate SNVS IP-block. Currently only the bits needed to
>> be able to emulate machine shutdown are implemented.
>>
>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.org
>> Cc: yurov...@gmail.com
>> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> ---
>>  hw/misc/Makefile.objs   |  1 +
>>  hw/misc/imx7_snvs.c | 83 
>> +
>>  include/hw/misc/imx7_snvs.h | 35 +++
>>  3 files changed, 119 insertions(+)
>>  create mode 100644 hw/misc/imx7_snvs.c
>>  create mode 100644 include/hw/misc/imx7_snvs.h
>>
>> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
>> index 4b2b705a6c..019886912c 100644
>> --- a/hw/misc/Makefile.objs
>> +++ b/hw/misc/Makefile.objs
>> @@ -35,6 +35,7 @@ obj-$(CONFIG_IMX) += imx6_ccm.o
>>  obj-$(CONFIG_IMX) += imx6_src.o
>>  obj-$(CONFIG_IMX) += imx7_ccm.o
>>  obj-$(CONFIG_IMX) += imx2_wdt.o
>> +obj-$(CONFIG_IMX) += imx7_snvs.o
>>  obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
>>  obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
>>  obj-$(CONFIG_MAINSTONE) += mst_fpga.o
>> diff --git a/hw/misc/imx7_snvs.c b/hw/misc/imx7_snvs.c
>> new file mode 100644
>> index 00..670b9f4639
>> --- /dev/null
>> +++ b/hw/misc/imx7_snvs.c
>> @@ -0,0 +1,83 @@
>> +/*
>> + * IMX7 Secure Non-Volatile Storage
>> + *
>> + * Copyright (c) 2017, Impinj, Inc.
>> + *
>> + * Author: Andrey Smirnov <andrew.smir...@gmail.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + *
>> + * Bare minimum emulation code needed to support being able to shut
>> + * down linux guest gracefully.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/misc/imx7_snvs.h"
>> +#include "qemu/log.h"
>> +#include "sysemu/sysemu.h"
>> +
>> +static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
>> +{
>> +return 0;
>> +}
>> +
>> +static void imx7_snvs_write(void *opaque, hwaddr offset,
>> +uint64_t v, unsigned size)
>> +{
>> +const uint32_t value = v;
>> +const uint32_t mask  = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
>> +
>> +if (offset == SNVS_LPCR && ((value & mask) == mask)) {
>> +qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
>> +}
>> +}
>> +
>> +static const struct MemoryRegionOps imx7_snvs_ops = {
>> +.read = imx7_snvs_read,
>
> Same here, you can remove the imx7_snvs_read() function since
> memory_region_dispatch_read() takes care of this and return 0.
>

Hmm, I don't think I agree both from reading code and trying this out.
Without .read callback the call chain ends up being the following
memory_region_dispatch_read() -> memory_region_dispatch_read1() ->
access_with_adjusted_size(..., memory_region_oldmmio_read_accessor,
...) -> memory_region_oldmmio_read_accessor() ->
mr->ops->old_mmio.read[ctz32(size)]() -> SEGFAULT

As much as I'd love to get rid of dummy .read callback, I don't see a
way to do that, unfortunately.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v4 09/14] pci: Add support for Designware IP block

2018-01-30 Thread Andrey Smirnov
On Tue, Jan 30, 2018 at 5:18 AM, Marcel Apfelbaum
<marcel.apfelb...@zoho.com> wrote:
> Hi Andrei,
>
> Sorry for letting you wait,
> I have some comments/questions below.
>
>
> On 16/01/2018 3:37, Andrey Smirnov wrote:
>>
>> Add code needed to get a functional PCI subsytem when using in
>> conjunction with upstream Linux guest (4.13+). Tested to work against
>> "e1000e" (network adapter, using MSI interrupts) as well as
>> "usb-ehci" (USB controller, using legacy PCI interrupts).
>>
>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.org
>> Cc: yurov...@gmail.com
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> ---
>>   default-configs/arm-softmmu.mak  |   2 +
>>   hw/pci-host/Makefile.objs|   2 +
>>   hw/pci-host/designware.c | 618
>> +++
>>   include/hw/pci-host/designware.h |  93 ++
>>   include/hw/pci/pci_ids.h |   2 +
>>   5 files changed, 717 insertions(+)
>>   create mode 100644 hw/pci-host/designware.c
>>   create mode 100644 include/hw/pci-host/designware.h
>>
>> diff --git a/default-configs/arm-softmmu.mak
>> b/default-configs/arm-softmmu.mak
>> index b0d6e65038..0c5ae914ed 100644
>> --- a/default-configs/arm-softmmu.mak
>> +++ b/default-configs/arm-softmmu.mak
>> @@ -132,3 +132,5 @@ CONFIG_GPIO_KEY=y
>>   CONFIG_MSF2=y
>>   CONFIG_FW_CFG_DMA=y
>>   CONFIG_XILINX_AXI=y
>> +CONFIG_PCI_DESIGNWARE=y
>> +
>> diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
>> index 9c7909cf44..0e2c0a123b 100644
>> --- a/hw/pci-host/Makefile.objs
>> +++ b/hw/pci-host/Makefile.objs
>> @@ -17,3 +17,5 @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
>>   common-obj-$(CONFIG_PCI_Q35) += q35.o
>>   common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
>>   common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
>> +
>> +common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
>> diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
>> new file mode 100644
>> index 00..98fff5e5f3
>> --- /dev/null
>> +++ b/hw/pci-host/designware.c
>> @@ -0,0 +1,618 @@
>> +/*
>> + * Copyright (c) 2017, Impinj, Inc.
>
> 2018 :)
>
>> + *
>> + * Designware PCIe IP block emulation
>> + *
>> + * This library is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2 of the License, or (at your option) any later version.
>> + *
>> + * This library is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with this library; if not, see
>> + * <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qapi/error.h"
>> +#include "hw/pci/msi.h"
>> +#include "hw/pci/pci_bridge.h"
>> +#include "hw/pci/pci_host.h"
>> +#include "hw/pci/pcie_port.h"
>> +#include "hw/pci-host/designware.h"
>> +
>> +#define PCIE_PORT_LINK_CONTROL  0x710
>> +
>> +#define PCIE_PHY_DEBUG_R1   0x72C
>> +#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP  BIT(4)
>> +
>> +#define PCIE_LINK_WIDTH_SPEED_CONTROL   0x80C
>> +
>> +#define PCIE_MSI_ADDR_LO0x820
>> +#define PCIE_MSI_ADDR_HI0x824
>> +#define PCIE_MSI_INTR0_ENABLE   0x828
>> +#define PCIE_MSI_INTR0_MASK 0x82C
>> +#define PCIE_MSI_INTR0_STATUS   0x830
>> +
>> +#define PCIE_ATU_VIEWPORT   0x900
>> +#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
>> +#define PCIE_ATU_REGION_OUTBOUND(0x0 << 31)
>> +#define PCIE_ATU_REGION_INDEX2  (0x2 << 0)
>> +#define PCIE_ATU_REGION_INDEX1  (0x1 << 0)
>> +#define PCIE_ATU_REGION_INDEX0  (0x0 << 0)
>> +#define PCIE_ATU_CR10x904
>> +#define PCIE_ATU_TYPE_MEM   (0x0 << 0)
>> +#define PCIE_ATU_TYPE_I

Re: [Qemu-devel] [PATCH v2] i.MX: Fix FEC/ENET receive funtions

2018-01-22 Thread Andrey Smirnov
On Mon, Jan 22, 2018 at 3:48 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:
> On 13 January 2018 at 11:34, Jean-Christophe Dubois <j...@tribudubois.net> 
> wrote:
>> The actual imx_eth_enable_rx() function is buggy.
>>
>> It updates s->regs[ENET_RDAR] after calling qemu_flush_queued_packets().
>>
>> qemu_flush_queued_packets() is going to call imx_XXX_receive() which itself
>> is going to call imx_eth_enable_rx().
>>
>> By updating s->regs[ENET_RDAR] after calling qemu_flush_queued_packets()
>> we end up updating the register with an outdated value which might
>> lead to disabling the receive function in the i.MX FEC/ENET device.
>>
>> This patch change the place where the register update is done so that the
>> register value stays up to date and the receive function can keep
>> running.
>>
>> Reported-by: Fyleo <fyle...@gmail.com>
>> Tested-by: Fyleo  <fyle...@gmail.com>
>> Signed-off-by: Jean-Christophe Dubois <j...@tribudubois.net>
>> ---
>
> Andrey, do you have an opinion on this patch, since you've been
> looking at i.MX code recently?
>

The rationale makes sense to me and patch looks like a good cleanup in
general, so FWIW:

Reviewed-by: Andrey Smirnov <andrew.smir...@gmail.com>

I also gave it a spin against my i.MX7 changes with doing basic things
like ping and scp of 1GB file, so I can give my:

Tested-by: Andrey Smirnov <andrew.smir...@gmail.com>

for that.

Thanks,
Andrey Smirnov


>> Change since v1:
>> 1. Rebase the patch on the updated master branch
>>
>>  hw/net/imx_fec.c | 8 ++--
>>  1 file changed, 2 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
>> index 4fb48f62ba..9506f9b69f 100644
>> --- a/hw/net/imx_fec.c
>> +++ b/hw/net/imx_fec.c
>> @@ -595,19 +595,16 @@ static void imx_eth_do_tx(IMXFECState *s, uint32_t 
>> index)
>>  static void imx_eth_enable_rx(IMXFECState *s, bool flush)
>>  {
>>  IMXFECBufDesc bd;
>> -bool rx_ring_full;
>>
>>  imx_fec_read_bd(, s->rx_descriptor);
>>
>> -rx_ring_full = !(bd.flags & ENET_BD_E);
>> +s->regs[ENET_RDAR] = (bd.flags & ENET_BD_E) ? ENET_RDAR_RDAR : 0;
>>
>> -if (rx_ring_full) {
>> +if (!s->regs[ENET_RDAR]) {
>>  FEC_PRINTF("RX buffer full\n");
>>  } else if (flush) {
>>  qemu_flush_queued_packets(qemu_get_queue(s->nic));
>>  }
>> -
>> -s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
>>  }
>>
>>  static void imx_eth_reset(DeviceState *d)
>> @@ -866,7 +863,6 @@ static void imx_eth_write(void *opaque, hwaddr offset, 
>> uint64_t value,
>>  case ENET_RDAR:
>>  if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
>>  if (!s->regs[index]) {
>> -s->regs[index] = ENET_RDAR_RDAR;
>>  imx_eth_enable_rx(s, true);
>>  }
>>  } else {
>> --
>> 2.14.1
>
> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
>
> thanks
> -- PMM



Re: [Qemu-devel] [PATCH v4 09/14] pci: Add support for Designware IP block

2018-01-17 Thread Andrey Smirnov
On Wed, Jan 17, 2018 at 7:23 AM, Marcel Apfelbaum
<marcel.apfelb...@zoho.com> wrote:
>
> Hi Peter,
>
>
> On 16/01/2018 16:34, Peter Maydell wrote:
>>
>> On 16 January 2018 at 01:37, Andrey Smirnov <andrew.smir...@gmail.com>
>> wrote:
>>>
>>> Add code needed to get a functional PCI subsytem when using in
>>> conjunction with upstream Linux guest (4.13+). Tested to work against
>>> "e1000e" (network adapter, using MSI interrupts) as well as
>>> "usb-ehci" (USB controller, using legacy PCI interrupts).
>>>
>>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>>> Cc: Jason Wang <jasow...@redhat.com>
>>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>>> Cc: qemu-devel@nongnu.org
>>> Cc: qemu-...@nongnu.org
>>> Cc: yurov...@gmail.com
>>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>>> ---
>>>   default-configs/arm-softmmu.mak  |   2 +
>>>   hw/pci-host/Makefile.objs|   2 +
>>>   hw/pci-host/designware.c | 618
>>> +++
>>>   include/hw/pci-host/designware.h |  93 ++
>>>   include/hw/pci/pci_ids.h |   2 +
>>>   5 files changed, 717 insertions(+)
>>>   create mode 100644 hw/pci-host/designware.c
>>>   create mode 100644 include/hw/pci-host/designware.h
>>
>> I'm not familiar enough with our PCI code to be able to review
>> this, I'm afraid. MST and Marcel are our PCI subsystem maintainers --
>> could one of you have a look at whether this seems to be a correct
>> implementation of a pcie host controller ?
>
>
> Sadly PCI Host bridges do not have a standard, each HW vendor
> can do pretty much what they want.
>
> That being said, if Andrey can point me to the PCI spec for the Designware
> PCI host bridge and what parts they implemented for it I can have a look,
> sure.
> (I will not be available for a week or so, but right after)
>

Just in case you still want this:

To the best of my knowledge, Synposys does not provide specification
for their PCIe IP to general public and I am in no way affiliated with
them, so I don't have any backchannels to get it any other way.

The next best thing to an actual spec, that I found to be pretty
useful, is PCIe chapter of i.MX6Q Reference Manual
(https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf   page
4049), which is what I used to implement the code in question.

Last, and probably the most important, "source of truth" was actual
Linux PCIe driver for i.MX/Designware which I used as a sort of
inverse reference implementation.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v4 00/14] Initial i.MX7 support

2018-01-16 Thread Andrey Smirnov
On Tue, Jan 16, 2018 at 7:08 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:
> On 16 January 2018 at 01:36, Andrey Smirnov <andrew.smir...@gmail.com> wrote:
>> Hi everyone,
>>
>> This v4 of the patch series containing the work that I've done in
>> order to enable support for i.MX7 emulation in QEMU.
>>
>> *NOTE*: Patches 1 and 2 are provided for the sake of completness and
>> are going to have to be adapted once Philippe's SD changes
>> land in master. As such, they are NOT ready to be
>> accepted/merged.
>
> I've just pushed a pullreq including Philippe's SD changes to master,
> so you should be able to do the final versions of these i.MX SD patches
> now. I've also I think now reviewed everything except the pci patch,
> which is a bit out of my competence area.

That's great news! I'll rebase on top of that as soon as I get a chance.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v4 08/14] i.MX: Add implementation of i.MX7 GPR IP block

2018-01-16 Thread Andrey Smirnov
On Mon, Jan 15, 2018 at 8:45 PM, Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> On 01/15/2018 10:37 PM, Andrey Smirnov wrote:
>> Add minimal code needed to allow upstream Linux guest to boot.
>>
>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.org
>> Cc: yurov...@gmail.com
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> ---
>>  hw/misc/Makefile.objs  |   1 +
>>  hw/misc/imx7_gpr.c | 119 
>> +
>>  include/hw/misc/imx7_gpr.h |  28 +++
>>  3 files changed, 148 insertions(+)
>>  create mode 100644 hw/misc/imx7_gpr.c
>>  create mode 100644 include/hw/misc/imx7_gpr.h
>>
>> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
>> index 019886912c..fce426eb75 100644
>> --- a/hw/misc/Makefile.objs
>> +++ b/hw/misc/Makefile.objs
>> @@ -36,6 +36,7 @@ obj-$(CONFIG_IMX) += imx6_src.o
>>  obj-$(CONFIG_IMX) += imx7_ccm.o
>>  obj-$(CONFIG_IMX) += imx2_wdt.o
>>  obj-$(CONFIG_IMX) += imx7_snvs.o
>> +obj-$(CONFIG_IMX) += imx7_gpr.o
>>  obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
>>  obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
>>  obj-$(CONFIG_MAINSTONE) += mst_fpga.o
>> diff --git a/hw/misc/imx7_gpr.c b/hw/misc/imx7_gpr.c
>> new file mode 100644
>> index 00..9e8ccea9e8
>> --- /dev/null
>> +++ b/hw/misc/imx7_gpr.c
>> @@ -0,0 +1,119 @@
>> +/*
>> + * Copyright (c) 2017, Impinj, Inc.
>> + *
>> + * i.MX7 GPR IP block emulation code
>> + *
>> + * Author: Andrey Smirnov <andrew.smir...@gmail.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + *
>> + * Bare minimum emulation code needed to support being able to shut
>> + * down linux guest gracefully.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/misc/imx7_gpr.h"
>> +#include "qemu/log.h"
>> +#include "sysemu/sysemu.h"
>> +
>> +enum IMX7GPRRegisters {
>> +IOMUXC_GPR0  = 0x00,
>> +IOMUXC_GPR1  = 0x04,
>> +IOMUXC_GPR2  = 0x08,
>> +IOMUXC_GPR3  = 0x0c,
>> +IOMUXC_GPR4  = 0x10,
>> +IOMUXC_GPR5  = 0x14,
>> +IOMUXC_GPR6  = 0x18,
>> +IOMUXC_GPR7  = 0x1c,
>> +IOMUXC_GPR8  = 0x20,
>> +IOMUXC_GPR9  = 0x24,
>> +IOMUXC_GPR10 = 0x28,
>> +IOMUXC_GPR11 = 0x2c,
>> +IOMUXC_GPR12 = 0x30,
>> +IOMUXC_GPR13 = 0x34,
>> +IOMUXC_GPR14 = 0x38,
>> +IOMUXC_GPR15 = 0x3c,
>> +IOMUXC_GPR16 = 0x40,
>> +IOMUXC_GPR17 = 0x44,
>> +IOMUXC_GPR18 = 0x48,
>> +IOMUXC_GPR19 = 0x4c,
>> +IOMUXC_GPR20 = 0x50,
>> +IOMUXC_GPR21 = 0x54,
>> +IOMUXC_GPR22 = 0x58,
>> +};
>> +
>> +#define IMX7D_GPR1_IRQ_MASK BIT(12)
>> +#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASKBIT(13)
>> +#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASKBIT(14)
>> +#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK (0x3 << 13)
>> +#define IMX7D_GPR1_ENET1_CLK_DIR_MASK   BIT(17)
>> +#define IMX7D_GPR1_ENET2_CLK_DIR_MASK   BIT(18)
>> +#define IMX7D_GPR1_ENET_CLK_DIR_MASK(0x3 << 17)
>> +
>> +#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI BIT(4)
>> +#define IMX7D_GPR12_PCIE_PHY_REFCLK_SEL BIT(5)
>> +#define IMX7D_GPR22_PCIE_PHY_PLL_LOCKED BIT(31)
>> +
>> +
>> +static uint64_t imx7_gpr_read(void *opaque, hwaddr offset, unsigned size)
>> +{
>> +if (offset == IOMUXC_GPR22) {
>> +return IMX7D_GPR22_PCIE_PHY_PLL_LOCKED;
>> +}
>> +
>> +return 0;
>> +}
>> +
>> +static void imx7_gpr_write(void *opaque, hwaddr offset,
>> +   uint64_t v, unsigned size)
>> +{
>
> If you ever respin, please add a trace point here (just copy/paste from
> another file from the same directory), and in the read() function.
>
> Linux will evolve and use more registers from this device (and the other
> devices you are modelling), and a Linux driver busy loop is likely to
> hang QEMU. A trace event will ease your board next user soon :)
>

Sure, will do.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v4 11/14] ARM: Add basic code to emulate A7MPCore DAP block

2018-01-16 Thread Andrey Smirnov
On Mon, Jan 15, 2018 at 8:32 PM, Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> Hi Andrey,
>
> On 01/15/2018 10:37 PM, Andrey Smirnov wrote:
>> Add minimal code to emulate A7MPCore DAP block needed to boot Linux
>> guest.
>
> I was not aware the DAP is accessed by upstream Linux...
>
> You sure this isn't rather part of some bootloader built-in self-test?
>

Yes, I am positive:

a) I don't run any bootloader and boot directly into Linux, so it's
just physically impossible
b) Here's the code:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/hwtracing/coresight?h=v4.15-rc8


>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.org
>> Cc: yurov...@gmail.com
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> ---
>>  hw/arm/Makefile.objs   |   2 +-
>>  hw/arm/coresight.c | 120 
>> +
>>  include/hw/arm/coresight.h |  24 +
>>  3 files changed, 145 insertions(+), 1 deletion(-)
>>  create mode 100644 hw/arm/coresight.c
>>  create mode 100644 include/hw/arm/coresight.h
>>
>> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
>> index 2794e086d6..692216e0cf 100644
>> --- a/hw/arm/Makefile.objs
>> +++ b/hw/arm/Makefile.objs
>> @@ -1,4 +1,4 @@
>> -obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
>> +obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o coresight.o
>>  obj-$(CONFIG_DIGIC) += digic_boards.o
>>  obj-y += integratorcp.o mainstone.o musicpal.o nseries.o
>>  obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
>> diff --git a/hw/arm/coresight.c b/hw/arm/coresight.c
>> new file mode 100644
>> index 00..d0a8c1b005
>> --- /dev/null
>> +++ b/hw/arm/coresight.c
>> @@ -0,0 +1,120 @@
>> +/*
>> + * Copyright (c) 2017, Impinj, Inc.
>> + *
>> + * CoreSight block emulation code
>> + *
>> + * Author: Andrey Smirnov <andrew.smir...@gmail.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/arm/coresight.h"
>> +#include "qemu/log.h"
>> +
>> +static uint64_t coresight_read(void *opaque, hwaddr offset,
>> +   unsigned size)
>> +{
>> +return 0;
>> +}
>> +
>> +static void coresight_write(void *opaque, hwaddr offset,
>> +uint64_t value, unsigned size)
>> +{
>> +}
>
> I assume you had to add this to bypass the memory_transaction_failures
> check.
>
>> +
>> +static const struct MemoryRegionOps coresight_ops = {
>> +.read = coresight_read,
>> +.write = coresight_write,
>> +.endianness = DEVICE_NATIVE_ENDIAN,
>> +.impl = {
>> +/*
>> + * Our device would not work correctly if the guest was doing
>> + * unaligned access. This might not be a limitation on the real
>> + * device but in practice there is no reason for a guest to access
>> + * this device unaligned.
>> + */
>> +.min_access_size = 4,
>> +.max_access_size = 4,
>> +.unaligned = false,
>> +},
>> +};
>> +
>> +static void a7mpcore_dap_init(Object *obj)
>> +{
>> +SysBusDevice *sd = SYS_BUS_DEVICE(obj);
>> +A7MPCoreDAPState *s = A7MPCORE_DAP(obj);
>> +
>> +memory_region_init(>container, obj, "a7mpcore-dap-container", 
>> 0x10);
>
> You can just use add this in fsl_imx7_realize():
>
>   create_unimplemented_device("a7mpcore-dap-container",
>           FSL_IMX7_A7MPCORE_DAP_ADDR,
>   0x10);
>
> to register a background region for the DAP (see "hw/misc/unimp.h")
>
> as a bonus, running with "-d unimp" you can trace the DAP access.
>
> So this model and those files are not necessary.
>

I am aware of create_unimplemented_device(), my reasoning for keeping
this code as a standalone class was to make it reusable for other
systems while providing more granular mapping (not just covering the
whole 0x10 bytes of memory). I'll convert the code to use
create_unimplemented_device() since we now have two votes in favor of
it.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH] hw/misc: Add code to emulate Xilinx Slave Serial port

2018-01-15 Thread Andrey Smirnov
On Tue, Dec 19, 2017 at 4:48 PM, Alistair Francis
<alistair.fran...@xilinx.com> wrote:
> On Thu, Dec 14, 2017 at 7:19 AM, Andrey Smirnov
> <andrew.smir...@gmail.com> wrote:
>> Add code to emulate Xilinx Slave Serial FPGA configuration port.
>>
>> Cc: "Edgar E. Iglesias" <edgar.igles...@gmail.com>
>> Cc: Alistair Francis <alistair.fran...@xilinx.com>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.org
>> Cc: yurov...@gmail.com
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>
> Hey,
>
> Thanks for the patch!
>
> I have some comments inline, if anything is unclear just email me back
> and I can provide more information or help.
>
>> ---
>>
>> Integrating this into a build system via "obj-y" might not be the best
>> way. Does this code need a dedicated CONFIG_ symbol?
>
> You probably don't need a specific one, there are already some Xilinx
> ones in there you can use.
>
> Maybe CONFIG_XILINX or CONFIG_XILINX_AXI
>

OK, will do if I ever re-spin this patch

>>
>> Thanks,
>> Andrey Smirnov
>>
>>
>>  hw/misc/Makefile.objs |   1 +
>>  hw/misc/xilinx_slave_serial.c | 105 
>> ++
>>  include/hw/misc/xilinx_slave_serial.h |  21 +++
>>  3 files changed, 127 insertions(+)
>>  create mode 100644 hw/misc/xilinx_slave_serial.c
>>  create mode 100644 include/hw/misc/xilinx_slave_serial.h
>
> You will need to connect this to a machine as well.
>
>>
>> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
>> index a68a201083..4599288e55 100644
>> --- a/hw/misc/Makefile.objs
>> +++ b/hw/misc/Makefile.objs
>> @@ -38,6 +38,7 @@ obj-$(CONFIG_IMX) += imx7_ccm.o
>>  obj-$(CONFIG_IMX) += imx2_wdt.o
>>  obj-$(CONFIG_IMX) += imx7_snvs.o
>>  obj-$(CONFIG_IMX) += imx7_gpr.o
>> +obj-y += xilinx_slave_serial.o
>>  obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
>>  obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
>>  obj-$(CONFIG_MAINSTONE) += mst_fpga.o
>> diff --git a/hw/misc/xilinx_slave_serial.c b/hw/misc/xilinx_slave_serial.c
>> new file mode 100644
>> index 00..607674fb60
>> --- /dev/null
>> +++ b/hw/misc/xilinx_slave_serial.c
>> @@ -0,0 +1,105 @@
>> +/*
>> + * Copyright (c) 2017, Impinj, Inc.
>> + *
>> + * Code to emulate programming "port" of Xilinx FPGA in Slave Serial
>> + * configuration connected via SPI, for more deatils see (p. 27):
>> + *
>> + * See https://www.xilinx.com/support/documentation/user_guides/ug380.pdf
>
> Ah, so this is for a Spartan-6 device. We don't have any QEMU support
> for Spartan-6. What are you trying to use this for?
>

The use-case for this patch is to fool FPGA configuration tools
running on the guest into beliving that they successfully configure
Spartan-6 device. I tested this code against
"drivers/fpga/xilinx-spi.c" from Linux kernel.

>> + *
>> + * Author: Andrey Smirnov <andrew.smir...@gmail.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/misc/xilinx_slave_serial.h"
>> +#include "qemu/log.h"
>> +
>> +enum {
>> +XILINX_SLAVE_SERIAL_STATE_RESET,
>> +XILINX_SLAVE_SERIAL_STATE_RECONFIGURATION,
>> +XILINX_SLAVE_SERIAL_STATE_DONE,
>> +};
>> +
>> +static void xilinx_slave_serial_update_outputs(XilinxSlaveSerialState 
>> *xlnxss)
>
> For function names try to use xlnx instead of xilinx, it just saves line 
> length.

Will fix if I re-spin this patch.

>
>> +{
>> +qemu_set_irq(xlnxss->done,
>> + xlnxss->state == XILINX_SLAVE_SERIAL_STATE_DONE);
>> +}
>> +
>> +static void xilinx_slave_serial_reset(DeviceState *dev)
>> +{
>> +XilinxSlaveSerialState *xlnxss = XILINX_SLAVE_SERIAL(dev);
>
> This is generally just called 's'.

OK, will fix if I re-spin this patch

>
>> +
>> +xlnxss->state = XILINX_SLAVE_SERIAL_STATE_RESET;
>> +
>> +xilinx_slave_serial_update_outputs(xlnxss);
>> +}
>> +
>> +static void xilinx_slave_serial_prog_b(void *opaque, int n, int level)
>> +{
>> +XilinxSlaveSerialState *xlnxss = XILINX_SLAVE_SERIAL(opaque);
>> +assert(n == 0);
>> +
>> +if (level) {
>> +xlnxss->state = XILINX_SLAVE_SERIAL_STATE_RECONFIGURATION;
>> +}
&g

[Qemu-devel] [PATCH v4 12/14] i.MX: Add i.MX7 SOC implementation.

2018-01-15 Thread Andrey Smirnov
The following interfaces are partially or fully emulated:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller

Tested to boot and work with upstream Linux (4.13+) guest.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   2 +
 hw/arm/fsl-imx7.c   | 583 
 include/hw/arm/fsl-imx7.h   | 223 +++
 4 files changed, 809 insertions(+)
 create mode 100644 hw/arm/fsl-imx7.c
 create mode 100644 include/hw/arm/fsl-imx7.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 0c5ae914ed..99fe1cd1fb 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -118,6 +118,7 @@ CONFIG_ALLWINNER_A10=y
 CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
+CONFIG_FSL_IMX7=y
 
 CONFIG_IMX_I2C=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 692216e0cf..ea47c8baed 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -20,3 +20,5 @@ obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
 obj-$(CONFIG_MPS2) += mps2.o
 obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
+
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
new file mode 100644
index 00..13f0aa2563
--- /dev/null
+++ b/hw/arm/fsl-imx7.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 SoC definitions
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * Based on hw/arm/fsl-imx6.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "hw/arm/fsl-imx7.h"
+#include "hw/misc/unimp.h"
+#include "sysemu/sysemu.h"
+#include "qemu/error-report.h"
+
+#define NAME_SIZE 20
+
+static void fsl_imx7_init(Object *obj)
+{
+BusState *sysbus = sysbus_get_default();
+FslIMX7State *s = FSL_IMX7(obj);
+char name[NAME_SIZE];
+int i;
+
+if (smp_cpus > FSL_IMX7_NUM_CPUS) {
+error_report("%s: Only %d CPUs are supported (%d requested)",
+ TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
+exit(1);
+}
+
+for (i = 0; i < smp_cpus; i++) {
+object_initialize(>cpu[i], sizeof(s->cpu[i]),
+  ARM_CPU_TYPE_NAME("cortex-a7"));
+snprintf(name, NAME_SIZE, "cpu%d", i);
+object_property_add_child(obj, name, OBJECT(>cpu[i]),
+  _fatal);
+}
+
+/*
+ * A7MPCORE
+ */
+object_initialize(>a7mpcore, sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
+qdev_set_parent_bus(DEVICE(>a7mpcore), sysbus);
+object_property_add_child(obj, "a7mpcore",
+  OBJECT(>a7mpcore), _fatal);
+
+object_initialize(>dap, sizeof(s->dap), TYPE_A7MPCORE_DAP);
+qdev_set_parent_bus(DEVICE(>dap), sysbus);
+object_property_add_child(obj, "a7mpcore-dap",
+  OBJECT(>dap), _fatal);
+
+/*
+ * GPIOs 1 to 7
+ */
+for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
+object_initialize(>gpio[i], sizeof(s->gpio[i]),
+  TYPE_IMX_GPIO);
+qdev_set_parent_bus(DEVICE(>gpio[i]), sysbus);
+snprintf(name, NAME_SIZE, "gpio%d", i);
+object_property_add_child(obj, name,
+  OBJECT(>gpio[i]), _fatal);
+}
+
+/*
+ * GPT1, 2, 3, 4
+ */
+for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
+object_

[Qemu-devel] [PATCH v4 13/14] hw/arm: Move virt's PSCI DT fixup code to arm/boot.c

2018-01-15 Thread Andrey Smirnov
Move virt's PSCI DT fixup code to arm/boot.c and set this fixup to
happen automatically for every board that doesn't mark "psci-conduit"
as disabled. This way emulated boards other than "virt" that rely on
PSIC for SMP could benefit from that code.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/arm/boot.c | 65 +++
 hw/arm/virt.c | 61 ---
 2 files changed, 65 insertions(+), 61 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index c2720c8046..18ada9152c 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -384,6 +384,69 @@ static void set_kernel_args_old(const struct arm_boot_info 
*info)
 }
 }
 
+static void fdt_add_psci_node(void *fdt)
+{
+uint32_t cpu_suspend_fn;
+uint32_t cpu_off_fn;
+uint32_t cpu_on_fn;
+uint32_t migrate_fn;
+ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
+const char *psci_method;
+int64_t psci_conduit;
+
+psci_conduit = object_property_get_int(OBJECT(armcpu),
+   "psci-conduit",
+   _abort);
+switch (psci_conduit) {
+case QEMU_PSCI_CONDUIT_DISABLED:
+return;
+case QEMU_PSCI_CONDUIT_HVC:
+psci_method = "hvc";
+break;
+case QEMU_PSCI_CONDUIT_SMC:
+psci_method = "smc";
+break;
+default:
+g_assert_not_reached();
+}
+
+qemu_fdt_add_subnode(fdt, "/psci");
+if (armcpu->psci_version == 2) {
+const char comp[] = "arm,psci-0.2\0arm,psci";
+qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
+
+cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
+if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
+cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
+cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
+migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
+} else {
+cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
+cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
+migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
+}
+} else {
+qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
+
+cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
+cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
+cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
+migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
+}
+
+/* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
+ * to the instruction that should be used to invoke PSCI functions.
+ * However, the device tree binding uses 'method' instead, so that is
+ * what we should use here.
+ */
+qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
+
+qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
+qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
+qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
+qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
+}
+
 /**
  * load_dtb() - load a device tree binary image into memory
  * @addr:   the address to load the image at
@@ -540,6 +603,8 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
 }
 }
 
+fdt_add_psci_node(fdt);
+
 if (binfo->modify_dtb) {
 binfo->modify_dtb(binfo, fdt);
 }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 151592b1e5..5586aba01c 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -242,66 +242,6 @@ static void create_fdt(VirtMachineState *vms)
 }
 }
 
-static void fdt_add_psci_node(const VirtMachineState *vms)
-{
-uint32_t cpu_suspend_fn;
-uint32_t cpu_off_fn;
-uint32_t cpu_on_fn;
-uint32_t migrate_fn;
-void *fdt = vms->fdt;
-ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
-const char *psci_method;
-
-switch (vms->psci_conduit) {
-case QEMU_PSCI_CONDUIT_DISABLED:
-return;
-case QEMU_PSCI_CONDUIT_HVC:
-psci_method = "hvc";
-break;
-case QEMU_PSCI_CONDUIT_SMC:
-psci_method = "smc";
-break;
-default:
-g_assert_not_reached();
-}
-
-qemu_fdt_add_subnode(fdt, "/psci");
-if (armcpu->psci_version == 2) {
-const char comp[] = "arm,psci-0.2\0arm,psci";
-qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
-
-cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
-if (arm_feature(>env, ARM_FEATURE_AAR

[Qemu-devel] [PATCH v4 10/14] usb: Add basic code to emulate Chipidea USB IP

2018-01-15 Thread Andrey Smirnov
Add code to emulate Chipidea USB IP (used in i.MX SoCs). Tested to
work against:

-usb -drive if=none,id=stick,file=usb.img,format=raw -device \
 usb-storage,bus=usb-bus.0,drive=stick

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/usb/Makefile.objs  |   1 +
 hw/usb/chipidea.c | 176 ++
 include/hw/usb/chipidea.h |  16 +
 3 files changed, 193 insertions(+)
 create mode 100644 hw/usb/chipidea.c
 create mode 100644 include/hw/usb/chipidea.h

diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index bdfead6701..5573c182d4 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -12,6 +12,7 @@ common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o
 common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
 
 obj-$(CONFIG_TUSB6010) += tusb6010.o
+obj-$(CONFIG_IMX)  += chipidea.o
 
 # emulated usb devices
 common-obj-$(CONFIG_USB) += dev-hub.o
diff --git a/hw/usb/chipidea.c b/hw/usb/chipidea.c
new file mode 100644
index 00..9bc8df448c
--- /dev/null
+++ b/hw/usb/chipidea.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Chipidea USB block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/usb/hcd-ehci.h"
+#include "hw/usb/chipidea.h"
+#include "qemu/log.h"
+
+enum {
+CHIPIDEA_USBx_DCIVERSION   = 0x000,
+CHIPIDEA_USBx_DCCPARAMS= 0x004,
+CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
+};
+
+static uint64_t chipidea_read(void *opaque, hwaddr offset,
+   unsigned size)
+{
+return 0;
+}
+
+static void chipidea_write(void *opaque, hwaddr offset,
+uint64_t value, unsigned size)
+{
+}
+
+static const struct MemoryRegionOps chipidea_ops = {
+.read = chipidea_read,
+.write = chipidea_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the
+ * real device but in practice there is no reason for a guest
+ * to access this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+switch (offset) {
+case CHIPIDEA_USBx_DCIVERSION:
+return 0x1;
+case CHIPIDEA_USBx_DCCPARAMS:
+/*
+ * Real hardware (at least i.MX7) will also report the
+ * controller as "Device Capable" (and 8 supported endpoints),
+ * but there doesn't seem to be much point in doing so, since
+ * we don't emulate that part.
+ */
+return CHIPIDEA_USBx_DCCPARAMS_HC;
+}
+
+return 0;
+}
+
+static void chipidea_dc_write(void *opaque, hwaddr offset,
+  uint64_t value, unsigned size)
+{
+}
+
+static const struct MemoryRegionOps chipidea_dc_ops = {
+.read = chipidea_dc_read,
+.write = chipidea_dc_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void chipidea_init(Object *obj)
+{
+EHCIState *ehci = _BUS_EHCI(obj)->ehci;
+ChipideaState *ci = CHIPIDEA(obj);
+int i;
+
+for (i = 0; i < ARRAY_SIZE(ci->iomem); i++) {
+const struct {
+const char *name;
+hwaddr offset;
+uint64_t size;
+const struct MemoryRegionOps *ops;
+} regions[ARRAY_SIZE(ci->iomem)] = {
+/*
+ * Registers located between offsets 0x000 and 0xFC
+ */
+{
+.name   = TYPE_CHIPIDEA ".misc",
+.offset = 0x000,
+.size   = 0x100,
+.ops= _ops,
+},
+/*
+ * Registers located between offsets 0x1A4 and 0x1DC
+ */
+{
+.name   = TYPE_CHIPIDEA ".endpoints",
+.offset = 0x1A4,
+.size   = 0x1DC - 0x1A4 + 4,
+.ops= _ops,
+},
+  

[Qemu-devel] [PATCH v4 11/14] ARM: Add basic code to emulate A7MPCore DAP block

2018-01-15 Thread Andrey Smirnov
Add minimal code to emulate A7MPCore DAP block needed to boot Linux
guest.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/arm/Makefile.objs   |   2 +-
 hw/arm/coresight.c | 120 +
 include/hw/arm/coresight.h |  24 +
 3 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/coresight.c
 create mode 100644 include/hw/arm/coresight.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 2794e086d6..692216e0cf 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
+obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o coresight.o
 obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-y += integratorcp.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
diff --git a/hw/arm/coresight.c b/hw/arm/coresight.c
new file mode 100644
index 00..d0a8c1b005
--- /dev/null
+++ b/hw/arm/coresight.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * CoreSight block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/arm/coresight.h"
+#include "qemu/log.h"
+
+static uint64_t coresight_read(void *opaque, hwaddr offset,
+   unsigned size)
+{
+return 0;
+}
+
+static void coresight_write(void *opaque, hwaddr offset,
+uint64_t value, unsigned size)
+{
+}
+
+static const struct MemoryRegionOps coresight_ops = {
+.read = coresight_read,
+.write = coresight_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void a7mpcore_dap_init(Object *obj)
+{
+SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+A7MPCoreDAPState *s = A7MPCORE_DAP(obj);
+
+memory_region_init(>container, obj, "a7mpcore-dap-container", 0x10);
+sysbus_init_mmio(sd, >container);
+
+memory_region_init_io(>ca7_atb_funnel,
+  obj,
+  _ops,
+  s,
+  TYPE_A7MPCORE_DAP ".ca7-atb-funnel",
+  0x1000);
+memory_region_add_subregion(>container, 0x41000, >ca7_atb_funnel);
+
+memory_region_init_io(>cpu0_etm,
+  obj,
+  _ops,
+  s,
+  TYPE_A7MPCORE_DAP ".cpu0-etm",
+  0x1000);
+memory_region_add_subregion(>container, 0x7C000, >cpu0_etm);
+
+memory_region_init_io(>atb_funnel,
+  obj,
+  _ops,
+  s,
+  TYPE_A7MPCORE_DAP ".atb-funnel",
+  0x1000);
+memory_region_add_subregion(>container, 0x83000, >atb_funnel);
+
+memory_region_init_io(>tmc_etb,
+  obj,
+  _ops,
+  s,
+  TYPE_A7MPCORE_DAP ".tmc-etb",
+  0x1000);
+memory_region_add_subregion(>container, 0x84000, >tmc_etb);
+
+memory_region_init_io(>tmc_etr,
+  obj,
+  _ops,
+  s,
+  TYPE_A7MPCORE_DAP ".tmc-etr",
+  0x1000);
+memory_region_add_subregion(>container, 0x86000, >tmc_etr);
+
+memory_region_init_io(>tpiu,
+  obj,
+  _ops,
+  s,
+  TYPE_A7MPCORE_DAP ".tpiu",
+  0x1000);
+memory_region_add_subregion(>container, 0x87000, >tpiu);
+}
+
+static void a7mpcore_dap_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc = "A7MPCore DAP Module";
+}
+
+static const TypeInfo a7mpcore_dap_info = {
+.name  = TYPE_A7MPCORE_DAP,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(A7MPCor

[Qemu-devel] [PATCH v4 05/14] i.MX: Add code to emulate i.MX7 SNVS IP-block

2018-01-15 Thread Andrey Smirnov
Add code to emulate SNVS IP-block. Currently only the bits needed to
be able to emulate machine shutdown are implemented.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/misc/Makefile.objs   |  1 +
 hw/misc/imx7_snvs.c | 83 +
 include/hw/misc/imx7_snvs.h | 35 +++
 3 files changed, 119 insertions(+)
 create mode 100644 hw/misc/imx7_snvs.c
 create mode 100644 include/hw/misc/imx7_snvs.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4b2b705a6c..019886912c 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -35,6 +35,7 @@ obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_IMX) += imx2_wdt.o
+obj-$(CONFIG_IMX) += imx7_snvs.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx7_snvs.c b/hw/misc/imx7_snvs.c
new file mode 100644
index 00..670b9f4639
--- /dev/null
+++ b/hw/misc/imx7_snvs.c
@@ -0,0 +1,83 @@
+/*
+ * IMX7 Secure Non-Volatile Storage
+ *
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Bare minimum emulation code needed to support being able to shut
+ * down linux guest gracefully.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx7_snvs.h"
+#include "qemu/log.h"
+#include "sysemu/sysemu.h"
+
+static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
+{
+return 0;
+}
+
+static void imx7_snvs_write(void *opaque, hwaddr offset,
+uint64_t v, unsigned size)
+{
+const uint32_t value = v;
+const uint32_t mask  = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
+
+if (offset == SNVS_LPCR && ((value & mask) == mask)) {
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+}
+}
+
+static const struct MemoryRegionOps imx7_snvs_ops = {
+.read = imx7_snvs_read,
+.write = imx7_snvs_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void imx7_snvs_init(Object *obj)
+{
+SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+IMX7SNVSState *s = IMX7_SNVS(obj);
+
+memory_region_init_io(>mmio, obj, _snvs_ops, s,
+  TYPE_IMX7_SNVS, 0x1000);
+
+sysbus_init_mmio(sd, >mmio);
+}
+
+static void imx7_snvs_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc  = "i.MX7 Secure Non-Volatile Storage Module";
+}
+
+static const TypeInfo imx7_snvs_info = {
+.name  = TYPE_IMX7_SNVS,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(IMX7SNVSState),
+.instance_init = imx7_snvs_init,
+.class_init= imx7_snvs_class_init,
+};
+
+static void imx7_snvs_register_type(void)
+{
+type_register_static(_snvs_info);
+}
+type_init(imx7_snvs_register_type)
diff --git a/include/hw/misc/imx7_snvs.h b/include/hw/misc/imx7_snvs.h
new file mode 100644
index 00..255f8f26f9
--- /dev/null
+++ b/include/hw/misc/imx7_snvs.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 SNVS block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef IMX7_SNVS_H
+#define IMX7_SNVS_H
+
+#include "qemu/bitops.h"
+#include "hw/sysbus.h"
+
+
+enum IMX7SNVSRegisters {
+SNVS_LPCR = 0x38,
+SNVS_LPCR_TOP   = BIT(6),
+SNVS_LPCR_DP_EN = BIT(5)
+};
+
+#define TYPE_IMX7_SNVS "imx7.snvs"
+#define IMX7_SNVS(obj) OBJECT_CHECK(IMX7SNVSState, (obj), TYPE_IMX7_SNVS)
+
+typedef struct IMX7SNVSState {
+/*  */
+SysBusDevice parent_obj;
+
+MemoryRegion mmio;
+} IMX7SNVSState;
+
+#endif /* IMX7_SNVS_H */
-- 
2.14.3




[Qemu-devel] [PATCH v4 09/14] pci: Add support for Designware IP block

2018-01-15 Thread Andrey Smirnov
Add code needed to get a functional PCI subsytem when using in
conjunction with upstream Linux guest (4.13+). Tested to work against
"e1000e" (network adapter, using MSI interrupts) as well as
"usb-ehci" (USB controller, using legacy PCI interrupts).

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 default-configs/arm-softmmu.mak  |   2 +
 hw/pci-host/Makefile.objs|   2 +
 hw/pci-host/designware.c | 618 +++
 include/hw/pci-host/designware.h |  93 ++
 include/hw/pci/pci_ids.h |   2 +
 5 files changed, 717 insertions(+)
 create mode 100644 hw/pci-host/designware.c
 create mode 100644 include/hw/pci-host/designware.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index b0d6e65038..0c5ae914ed 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -132,3 +132,5 @@ CONFIG_GPIO_KEY=y
 CONFIG_MSF2=y
 CONFIG_FW_CFG_DMA=y
 CONFIG_XILINX_AXI=y
+CONFIG_PCI_DESIGNWARE=y
+
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 9c7909cf44..0e2c0a123b 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -17,3 +17,5 @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
 common-obj-$(CONFIG_PCI_Q35) += q35.o
 common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
 common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
+
+common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
new file mode 100644
index 00..98fff5e5f3
--- /dev/null
+++ b/hw/pci-host/designware.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Designware PCIe IP block emulation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/pci-host/designware.h"
+
+#define PCIE_PORT_LINK_CONTROL  0x710
+
+#define PCIE_PHY_DEBUG_R1   0x72C
+#define PCIE_PHY_DEBUG_R1_XMLH_LINK_UP  BIT(4)
+
+#define PCIE_LINK_WIDTH_SPEED_CONTROL   0x80C
+
+#define PCIE_MSI_ADDR_LO0x820
+#define PCIE_MSI_ADDR_HI0x824
+#define PCIE_MSI_INTR0_ENABLE   0x828
+#define PCIE_MSI_INTR0_MASK 0x82C
+#define PCIE_MSI_INTR0_STATUS   0x830
+
+#define PCIE_ATU_VIEWPORT   0x900
+#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
+#define PCIE_ATU_REGION_OUTBOUND(0x0 << 31)
+#define PCIE_ATU_REGION_INDEX2  (0x2 << 0)
+#define PCIE_ATU_REGION_INDEX1  (0x1 << 0)
+#define PCIE_ATU_REGION_INDEX0  (0x0 << 0)
+#define PCIE_ATU_CR10x904
+#define PCIE_ATU_TYPE_MEM   (0x0 << 0)
+#define PCIE_ATU_TYPE_IO(0x2 << 0)
+#define PCIE_ATU_TYPE_CFG0  (0x4 << 0)
+#define PCIE_ATU_TYPE_CFG1  (0x5 << 0)
+#define PCIE_ATU_CR20x908
+#define PCIE_ATU_ENABLE (0x1 << 31)
+#define PCIE_ATU_BAR_MODE_ENABLE(0x1 << 30)
+#define PCIE_ATU_LOWER_BASE 0x90C
+#define PCIE_ATU_UPPER_BASE 0x910
+#define PCIE_ATU_LIMIT  0x914
+#define PCIE_ATU_LOWER_TARGET   0x918
+#define PCIE_ATU_BUS(x) (((x) >> 24) & 0xff)
+#define PCIE_ATU_DEVFN(x)   (((x) >> 16) & 0xff)
+#define PCIE_ATU_UPPER_TARGET   0x91C
+
+static DesignwarePCIEHost *
+designware_pcie_root_to_host(DesignwarePCIERoot *root)
+{
+BusState *bus = qdev_get_parent_bus(DEVICE(root));
+return DESIGNWARE_PCIE_HOST(bus->parent);
+}
+
+static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
+   uint64_t val, unsigned len)
+{
+DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(opaque);
+DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
+
+ro

[Qemu-devel] [PATCH v4 06/14] i.MX: Add code to emulate GPCv2 IP block

2018-01-15 Thread Andrey Smirnov
Add minimal code needed to allow upstream Linux guest to boot.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/intc/Makefile.objs   |   2 +-
 hw/intc/imx_gpcv2.c | 125 
 include/hw/intc/imx_gpcv2.h |  22 
 3 files changed, 148 insertions(+), 1 deletion(-)
 create mode 100644 hw/intc/imx_gpcv2.c
 create mode 100644 include/hw/intc/imx_gpcv2.h

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index ae358569a1..2252181ac9 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -4,7 +4,7 @@ common-obj-$(CONFIG_PL190) += pl190.o
 common-obj-$(CONFIG_PUV3) += puv3_intc.o
 common-obj-$(CONFIG_XILINX) += xilinx_intc.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o
-common-obj-$(CONFIG_IMX) += imx_avic.o
+common-obj-$(CONFIG_IMX) += imx_avic.o imx_gpcv2.o
 common-obj-$(CONFIG_LM32) += lm32_pic.o
 common-obj-$(CONFIG_REALVIEW) += realview_gic.o
 common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c
new file mode 100644
index 00..496ed31b78
--- /dev/null
+++ b/hw/intc/imx_gpcv2.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 GPCv2 block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/intc/imx_gpcv2.h"
+#include "qemu/log.h"
+
+#define GPC_PU_PGC_SW_PUP_REQ   0x0f8
+#define GPC_PU_PGC_SW_PDN_REQ   0x104
+
+#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
+#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
+#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
+#define PCIE_PHY_SW_Pxx_REQ BIT(1)
+#define MIPI_PHY_SW_Pxx_REQ BIT(0)
+
+
+static void imx_gpcv2_reset(DeviceState *dev)
+{
+IMXGPCv2State *s = IMX_GPCV2(dev);
+
+memset(s->regs, 0, sizeof(s->regs));
+}
+
+static uint64_t imx_gpcv2_read(void *opaque, hwaddr offset,
+   unsigned size)
+{
+IMXGPCv2State *s = opaque;
+
+return s->regs[offset / sizeof(uint32_t)];
+}
+
+static void imx_gpcv2_write(void *opaque, hwaddr offset,
+uint64_t value, unsigned size)
+{
+IMXGPCv2State *s = opaque;
+const size_t idx = offset / sizeof(uint32_t);
+
+s->regs[idx] = value;
+
+/*
+ * Real HW will clear those bits once as a way to indicate that
+ * power up request is complete
+ */
+if (offset == GPC_PU_PGC_SW_PUP_REQ ||
+offset == GPC_PU_PGC_SW_PDN_REQ) {
+s->regs[idx] &= ~(USB_HSIC_PHY_SW_Pxx_REQ |
+  USB_OTG2_PHY_SW_Pxx_REQ |
+  USB_OTG1_PHY_SW_Pxx_REQ |
+  PCIE_PHY_SW_Pxx_REQ |
+  MIPI_PHY_SW_Pxx_REQ);
+}
+}
+
+static const struct MemoryRegionOps imx_gpcv2_ops = {
+.read = imx_gpcv2_read,
+.write = imx_gpcv2_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void imx_gpcv2_init(Object *obj)
+{
+SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+IMXGPCv2State *s = IMX_GPCV2(obj);
+
+memory_region_init_io(>iomem,
+  obj,
+  _gpcv2_ops,
+  s,
+  TYPE_IMX_GPCV2 ".iomem",
+  sizeof(s->regs));
+sysbus_init_mmio(sd, >iomem);
+}
+
+static const VMStateDescription vmstate_imx_gpcv2 = {
+.name = TYPE_IMX_GPCV2,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(regs, IMXGPCv2State, GPC_NUM),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void imx_gpcv2_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->reset = imx_gpcv2_reset;
+dc->vmsd  = _imx_gpcv2;
+dc->desc  = "i.MX GPCv2 Module";
+}
+
+static const TypeInfo imx_gpcv2_info = {
+.name  = TYPE_IMX_GPCV2,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(IMXGPCv2State),
+.instance_init = imx_gpcv2_init,
+.class_init= imx_gpcv2_class_init,
+};
+
+static void

[Qemu-devel] [PATCH v4 04/14] i.MX: Add code to emulate i.MX2 watchdog IP block

2018-01-15 Thread Andrey Smirnov
Add enough code to emulate i.MX2 watchdog IP block so it would be
possible to reboot the machine running Linux Guest.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/misc/Makefile.objs  |  1 +
 hw/misc/imx2_wdt.c | 89 ++
 include/hw/misc/imx2_wdt.h | 33 +
 3 files changed, 123 insertions(+)
 create mode 100644 hw/misc/imx2_wdt.c
 create mode 100644 include/hw/misc/imx2_wdt.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a28e5e49b0..4b2b705a6c 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -34,6 +34,7 @@ obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
+obj-$(CONFIG_IMX) += imx2_wdt.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c
new file mode 100644
index 00..76bb98a525
--- /dev/null
+++ b/hw/misc/imx2_wdt.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX2 Watchdog IP block
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/bitops.h"
+#include "qemu/osdep.h"
+#include "sysemu/watchdog.h"
+
+#include "hw/misc/imx2_wdt.h"
+
+#define IMX2_WDT_WCR_WDABIT(5)  /* -> External Reset WDOG_B */
+#define IMX2_WDT_WCR_SRSBIT(4)  /* -> Software Reset Signal */
+
+static uint64_t imx2_wdt_read(void *opaque, hwaddr addr,
+  unsigned int size)
+{
+return 0;
+}
+
+static void imx2_wdt_write(void *opaque, hwaddr addr,
+   uint64_t value, unsigned int size)
+{
+if (addr == IMX2_WDT_WCR &&
+(value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
+watchdog_perform_action();
+}
+}
+
+static const MemoryRegionOps imx2_wdt_ops = {
+.read  = imx2_wdt_read,
+.write = imx2_wdt_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the
+ * real device but in practice there is no reason for a guest
+ * to access this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void imx2_wdt_realize(DeviceState *dev, Error **errp)
+{
+IMX2WdtState *s = IMX2_WDT(dev);
+
+memory_region_init_io(>mmio, OBJECT(dev),
+  _wdt_ops, s,
+  TYPE_IMX2_WDT".mmio",
+  IMX2_WDT_REG_NUM * sizeof(uint16_t));
+sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
+}
+
+static void imx2_wdt_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = imx2_wdt_realize;
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static const TypeInfo imx2_wdt_info = {
+.name  = TYPE_IMX2_WDT,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(IMX2WdtState),
+.class_init= imx2_wdt_class_init,
+};
+
+static WatchdogTimerModel model = {
+.wdt_name = "imx2-watchdog",
+.wdt_description = "i.MX2 Watchdog",
+};
+
+static void imx2_wdt_register_type(void)
+{
+watchdog_add_model();
+type_register_static(_wdt_info);
+}
+type_init(imx2_wdt_register_type)
diff --git a/include/hw/misc/imx2_wdt.h b/include/hw/misc/imx2_wdt.h
new file mode 100644
index 00..8afc99a10e
--- /dev/null
+++ b/include/hw/misc/imx2_wdt.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX2 Watchdog IP block
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef IMX2_WDT_H
+#define IMX2_WDT_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_IMX2_WDT "imx2.wdt"
+#define IMX2_WDT(obj) OBJECT_CHECK(IMX2WdtState, (obj), TYPE_IMX2_WDT)
+
+enum IMX2WdtRegisters {
+IMX2_WDT_WCR = 0x,
+IMX2_WDT_REG_NUM = 0x0008 / sizeof(uint16_t) + 1,
+};
+
+
+typedef struct IMX2WdtState {
+/*  */
+SysBusDevice parent_obj;
+
+MemoryRegion mmio;
+} IMX2WdtState;
+
+#endif /* IMX7_SNVS_H */
-- 
2.14.3




[Qemu-devel] [PATCH v4 03/14] i.MX: Add code to emulate i.MX7 CCM, PMU and ANALOG IP blocks

2018-01-15 Thread Andrey Smirnov
Add minimal code needed to allow upstream Linux guest to boot.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx7_ccm.c | 277 +
 include/hw/misc/imx7_ccm.h | 139 +++
 3 files changed, 417 insertions(+)
 create mode 100644 hw/misc/imx7_ccm.c
 create mode 100644 include/hw/misc/imx7_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d517f83e81..a28e5e49b0 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -33,6 +33,7 @@ obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_IMX) += imx6_ccm.o
 obj-$(CONFIG_IMX) += imx6_src.o
+obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
new file mode 100644
index 00..23855df02a
--- /dev/null
+++ b/hw/misc/imx7_ccm.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+
+#include "hw/misc/imx7_ccm.h"
+
+static void imx7_analog_reset(DeviceState *dev)
+{
+IMX7AnalogState *s = IMX7_ANALOG(dev);
+
+memset(s->pmu, 0, sizeof(s->pmu));
+memset(s->analog, 0, sizeof(s->analog));
+
+s->analog[ANALOG_PLL_ARM] = 0x2042;
+s->analog[ANALOG_PLL_DDR] = 0x0060302c;
+s->analog[ANALOG_PLL_DDR_SS]  = 0x;
+s->analog[ANALOG_PLL_DDR_NUM] = 0x06aaac4d;
+s->analog[ANALOG_PLL_DDR_DENOM]   = 0x13ec;
+s->analog[ANALOG_PLL_480] = 0x2000;
+s->analog[ANALOG_PLL_480A]= 0x52605a56;
+s->analog[ANALOG_PLL_480B]= 0x52525216;
+s->analog[ANALOG_PLL_ENET]= 0x1fc0;
+s->analog[ANALOG_PLL_AUDIO]   = 0x0001301b;
+s->analog[ANALOG_PLL_AUDIO_SS]= 0x;
+s->analog[ANALOG_PLL_AUDIO_NUM]   = 0x05f5e100;
+s->analog[ANALOG_PLL_AUDIO_DENOM] = 0x2964619c;
+s->analog[ANALOG_PLL_VIDEO]   = 0x0008201b;
+s->analog[ANALOG_PLL_VIDEO_SS]= 0x;
+s->analog[ANALOG_PLL_VIDEO_NUM]   = 0xf699;
+s->analog[ANALOG_PLL_VIDEO_DENOM] = 0x000f4240;
+s->analog[ANALOG_PLL_MISC0]   = 0x;
+
+/* all PLLs need to be locked */
+s->analog[ANALOG_PLL_ARM]   |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_DDR]   |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_480]   |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_480A]  |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_480B]  |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_ENET]  |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_AUDIO] |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_VIDEO] |= ANALOG_PLL_LOCK;
+s->analog[ANALOG_PLL_MISC0] |= ANALOG_PLL_LOCK;
+
+/*
+ * Since I couldn't find any info about this in the reference
+ * manual the value of this register is based strictly on matching
+ * what Linux kernel expects it to be.
+ */
+s->analog[ANALOG_DIGPROG]  = 0x72;
+/*
+ * Set revision to be 1.0 (Arbitrary choice, no particular
+ * reason).
+ */
+s->analog[ANALOG_DIGPROG] |= 0x10;
+}
+
+static void imx7_ccm_reset(DeviceState *dev)
+{
+IMX7CCMState *s = IMX7_CCM(dev);
+
+memset(s->ccm, 0, sizeof(s->ccm));
+}
+
+#define CCM_INDEX(offset)   (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
+#define CCM_BITOP(offset)   ((offset) & (hwaddr)0xF)
+
+enum {
+CCM_BITOP_NONE = 0x00,
+CCM_BITOP_SET  = 0x04,
+CCM_BITOP_CLR  = 0x08,
+CCM_BITOP_TOG  = 0x0C,
+};
+
+static uint64_t imx7_set_clr_tog_read(void *opaque, hwaddr offset,
+  unsigned size)
+{
+const uint32_t *mmio = opaque;
+
+return mmio[CCM_INDEX(offset)];
+}
+
+static void imx7_set_clr_tog_write(void *opaque, hwaddr offset,
+   uint64_t value, unsigned size)
+{
+const uint8_t  bitop = CCM_BITOP(offset);
+const uint32_t index = CCM_INDEX(offset);
+uint32_t *mmio = opaque;
+
+switch (bitop) {
+case CCM_BITOP_NONE:
+mmio[index]  = value;
+break;
+case CCM_BITOP_SET:
+mmio[index] |= value;
+break;
+case CCM_BITOP_CLR:
+mmio[index] &= ~value;
+break;
+case CCM_BITOP_TOG:
+mmio[ind

[Qemu-devel] [PATCH v4 08/14] i.MX: Add implementation of i.MX7 GPR IP block

2018-01-15 Thread Andrey Smirnov
Add minimal code needed to allow upstream Linux guest to boot.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/misc/Makefile.objs  |   1 +
 hw/misc/imx7_gpr.c | 119 +
 include/hw/misc/imx7_gpr.h |  28 +++
 3 files changed, 148 insertions(+)
 create mode 100644 hw/misc/imx7_gpr.c
 create mode 100644 include/hw/misc/imx7_gpr.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 019886912c..fce426eb75 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -36,6 +36,7 @@ obj-$(CONFIG_IMX) += imx6_src.o
 obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_IMX) += imx2_wdt.o
 obj-$(CONFIG_IMX) += imx7_snvs.o
+obj-$(CONFIG_IMX) += imx7_gpr.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx7_gpr.c b/hw/misc/imx7_gpr.c
new file mode 100644
index 00..9e8ccea9e8
--- /dev/null
+++ b/hw/misc/imx7_gpr.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 GPR IP block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * Bare minimum emulation code needed to support being able to shut
+ * down linux guest gracefully.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/imx7_gpr.h"
+#include "qemu/log.h"
+#include "sysemu/sysemu.h"
+
+enum IMX7GPRRegisters {
+IOMUXC_GPR0  = 0x00,
+IOMUXC_GPR1  = 0x04,
+IOMUXC_GPR2  = 0x08,
+IOMUXC_GPR3  = 0x0c,
+IOMUXC_GPR4  = 0x10,
+IOMUXC_GPR5  = 0x14,
+IOMUXC_GPR6  = 0x18,
+IOMUXC_GPR7  = 0x1c,
+IOMUXC_GPR8  = 0x20,
+IOMUXC_GPR9  = 0x24,
+IOMUXC_GPR10 = 0x28,
+IOMUXC_GPR11 = 0x2c,
+IOMUXC_GPR12 = 0x30,
+IOMUXC_GPR13 = 0x34,
+IOMUXC_GPR14 = 0x38,
+IOMUXC_GPR15 = 0x3c,
+IOMUXC_GPR16 = 0x40,
+IOMUXC_GPR17 = 0x44,
+IOMUXC_GPR18 = 0x48,
+IOMUXC_GPR19 = 0x4c,
+IOMUXC_GPR20 = 0x50,
+IOMUXC_GPR21 = 0x54,
+IOMUXC_GPR22 = 0x58,
+};
+
+#define IMX7D_GPR1_IRQ_MASK BIT(12)
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASKBIT(13)
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASKBIT(14)
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK (0x3 << 13)
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK   BIT(17)
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK   BIT(18)
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK(0x3 << 17)
+
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI BIT(4)
+#define IMX7D_GPR12_PCIE_PHY_REFCLK_SEL BIT(5)
+#define IMX7D_GPR22_PCIE_PHY_PLL_LOCKED BIT(31)
+
+
+static uint64_t imx7_gpr_read(void *opaque, hwaddr offset, unsigned size)
+{
+if (offset == IOMUXC_GPR22) {
+return IMX7D_GPR22_PCIE_PHY_PLL_LOCKED;
+}
+
+return 0;
+}
+
+static void imx7_gpr_write(void *opaque, hwaddr offset,
+   uint64_t v, unsigned size)
+{
+}
+
+static const struct MemoryRegionOps imx7_gpr_ops = {
+.read = imx7_gpr_read,
+.write = imx7_gpr_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the
+ * real device but in practice there is no reason for a guest
+ * to access this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void imx7_gpr_init(Object *obj)
+{
+SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+IMX7GPRState *s = IMX7_GPR(obj);
+
+memory_region_init_io(>mmio, obj, _gpr_ops, s,
+  TYPE_IMX7_GPR, 64 * 1024);
+sysbus_init_mmio(sd, >mmio);
+}
+
+static void imx7_gpr_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc  = "i.MX7 General Purpose Registers Module";
+}
+
+static const TypeInfo imx7_gpr_info = {
+.name  = TYPE_IMX7_GPR,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(IMX7GPRState),
+.instance_init = imx7_gpr_init,
+.class_init= imx7_gpr_class_init,
+};
+
+static void imx7_gpr_register_type(void)
+{
+type_register_static(_gpr_info);
+}
+type_init(imx7_gpr_register_type)
diff --git a/include/hw/misc/imx7_gpr.h b/include/hw/misc/imx7_gpr.h
new file mode 100644
index 00..e19373d274
--- /dev/null
+++ b/include/hw/misc/imx7_gpr.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * i.MX7 GPR IP block emulation code
+ *
+ * Author: Andrey Smirnov <an

[Qemu-devel] [PATCH v4 01/14] sdhci: Add i.MX specific subtype of SDHCI

2018-01-15 Thread Andrey Smirnov
IP block found on several generations of i.MX family does not use
vanilla SDHCI implementation and it comes with a number of quirks.

Introduce i.MX SDHCI subtype of SDHCI block to add code necessary to
support unmodified Linux guest driver.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/sd/sdhci-internal.h |  19 +
 hw/sd/sdhci.c  | 228 -
 include/hw/sd/sdhci.h  |  14 +++
 3 files changed, 259 insertions(+), 2 deletions(-)

diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index 161177cf39..b86ac0791b 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -85,12 +85,18 @@
 
 /* R/W Host control Register 0x0 */
 #define SDHC_HOSTCTL   0x28
+#define SDHC_CTRL_LED  0x01
 #define SDHC_CTRL_DMA_CHECK_MASK   0x18
 #define SDHC_CTRL_SDMA 0x00
 #define SDHC_CTRL_ADMA1_32 0x08
 #define SDHC_CTRL_ADMA2_32 0x10
 #define SDHC_CTRL_ADMA2_64 0x18
 #define SDHC_DMA_TYPE(x)   ((x) & SDHC_CTRL_DMA_CHECK_MASK)
+#define SDHC_CTRL_4BITBUS  0x02
+#define SDHC_CTRL_8BITBUS  0x20
+#define SDHC_CTRL_CDTEST_INS   0x40
+#define SDHC_CTRL_CDTEST_EN0x80
+
 
 /* R/W Power Control Register 0x0 */
 #define SDHC_PWRCON0x29
@@ -229,4 +235,17 @@ enum {
 
 extern const VMStateDescription sdhci_vmstate;
 
+
+#define ESDHC_MIX_CTRL  0x48
+#define ESDHC_VENDOR_SPEC   0xc0
+#define ESDHC_DLL_CTRL  0x60
+
+#define ESDHC_TUNING_CTRL   0xcc
+#define ESDHC_TUNE_CTRL_STATUS  0x68
+#define ESDHC_WTMK_LVL  0x44
+
+#define ESDHC_CTRL_4BITBUS  (0x1 << 1)
+#define ESDHC_CTRL_8BITBUS  (0x2 << 1)
+
+
 #endif
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index b23d1bfb97..a35e11e89d 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -265,7 +265,8 @@ static void sdhci_send_command(SDHCIState *s)
 }
 }
 
-if ((s->norintstsen & SDHC_NISEN_TRSCMP) &&
+if (!(s->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
+(s->norintstsen & SDHC_NISEN_TRSCMP) &&
 (s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
 s->norintsts |= SDHC_NIS_TRSCMP;
 }
@@ -1194,6 +1195,8 @@ static void sdhci_initfn(SDHCIState *s)
 
 s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
sdhci_raise_insertion_irq, s);
 s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, 
s);
+
+s->io_ops = _mmio_ops;
 }
 
 static void sdhci_uninitfn(SDHCIState *s)
@@ -1354,7 +1357,7 @@ static void sdhci_sysbus_realize(DeviceState *dev, Error 
** errp)
 s->buf_maxsz = sdhci_get_fifolen(s);
 s->fifo_buffer = g_malloc0(s->buf_maxsz);
 sysbus_init_irq(sbd, >irq);
-memory_region_init_io(>iomem, OBJECT(s), _mmio_ops, s, "sdhci",
+memory_region_init_io(>iomem, OBJECT(s), s->io_ops, s, "sdhci",
 SDHC_REGISTERS_MAP_SIZE);
 sysbus_init_mmio(sbd, >iomem);
 }
@@ -1393,11 +1396,232 @@ static const TypeInfo sdhci_bus_info = {
 .class_init = sdhci_bus_class_init,
 };
 
+static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
+{
+SDHCIState *s = SYSBUS_SDHCI(opaque);
+uint32_t ret;
+uint16_t hostctl;
+
+switch (offset) {
+default:
+return sdhci_read(opaque, offset, size);
+
+case SDHC_HOSTCTL:
+/*
+ * For a detailed explanation on the following bit
+ * manipulation code see comments in a similar part of
+ * usdhc_write()
+ */
+hostctl = SDHC_DMA_TYPE(s->hostctl) << (8 - 3);
+
+if (s->hostctl & SDHC_CTRL_8BITBUS) {
+hostctl |= ESDHC_CTRL_8BITBUS;
+}
+
+if (s->hostctl & SDHC_CTRL_4BITBUS) {
+hostctl |= ESDHC_CTRL_4BITBUS;
+}
+
+ret  = hostctl;
+ret |= (uint32_t)s->blkgap << 16;
+ret |= (uint32_t)s->wakcon << 24;
+
+break;
+
+case ESDHC_DLL_CTRL:
+case ESDHC_TUNE_CTRL_STATUS:
+case 0x6c:
+case ESDHC_TUNING_CTRL:
+case ESDHC_VENDOR_SPEC:
+case ESDHC_MIX_CTRL:
+case ESDHC_WTMK_LVL:
+ret = 0;
+break;
+}
+
+return ret;
+}
+
+static void
+usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
+{
+SDHCIState *s = SYSBUS_SDHCI(opaque);
+uint8_t hostctl;
+uint32_t value = (uint32_t)val;
+
+switch (offset) {
+

[Qemu-devel] [PATCH v4 00/14] Initial i.MX7 support

2018-01-15 Thread Andrey Smirnov
Hi everyone,

This v4 of the patch series containing the work that I've done in
order to enable support for i.MX7 emulation in QEMU.

*NOTE*: Patches 1 and 2 are provided for the sake of completness and
are going to have to be adapted once Philippe's SD changes
land in master. As such, they are NOT ready to be
accepted/merged.

As the one before last commit in the series states the supported i.MX7
features are:

* up to 2 Cortex A9 cores (SMP works with PSCI)
* A7 MPCORE (identical to A15 MPCORE)
* 4 GPTs modules
* 7 GPIO controllers
* 2 IOMUXC controllers
* 1 CCM module
* 1 SVNS module
* 1 SRC module
* 1 GPCv2 controller
* 4 eCSPI controllers
* 4 I2C controllers
* 7 i.MX UART controllers
* 2 FlexCAN controllers
* 2 Ethernet controllers (FEC)
* 3 SD controllers (USDHC)
* 4 WDT modules
* 1 SDMA module
* 1 GPR module
* 2 USBMISC modules
* 2 ADC modules
* 1 PCIe controller
* 3 USB controllers
* 1 LCD controller
* 1 ARMv7 DAP IP block

Feedback is welcome!

Changes since [v3]:

- Changes to FEC were split into a separate set and merged to master

- Patchest is rebased on latest master

- Converted to use PSCI DT fixup code that is shared with virt
  platform (now relocated to live in arm/boot.c)

- Large number of dummy block were converted to use
  create_unimplemented_device() as opposed to its own dedicated
  type

- Incorporated varios small feedback items

- Collected Reviewed-by tags from Peter

Changes since [v2]:

- Added stubs for more blocks that were causing memory
  transactions when booting Linux guest as were revealed by
  additional testing of the patchest

- Added proper USB emulation code, so now it should be possible to
  emulated guest's USB bus

Changes since [v1]:

- Patchset no longer relies on "ignore_memory_transaction_failures = false"
  for its functionality

- As a consequnce of implementing the above a number of patches
  implementing dummy IP block emulation as well as PCIe emulation
  patches that I alluded to in [v1] are now included in this patch
  series

- "has_el3" property is no longer being set to "false" as a part
  of intialization of A7 CPU. I couldn't reproduce the issues that
  I thought I was having, so I just dropped that code.

- A number of smaller feedback items from Peter and other has been
  incorporated into the patches.


Thanks,
Andrey Smirnov

[v3] https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg04236.html
[v2] https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05516.html
[v1] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg04770.html

Andrey Smirnov (14):
  sdhci: Add i.MX specific subtype of SDHCI
  hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC
  i.MX: Add code to emulate i.MX7 CCM, PMU and ANALOG IP blocks
  i.MX: Add code to emulate i.MX2 watchdog IP block
  i.MX: Add code to emulate i.MX7 SNVS IP-block
  i.MX: Add code to emulate GPCv2 IP block
  i.MX: Add i.MX7 GPT variant
  i.MX: Add implementation of i.MX7 GPR IP block
  pci: Add support for Designware IP block
  usb: Add basic code to emulate Chipidea USB IP
  ARM: Add basic code to emulate A7MPCore DAP block
  i.MX: Add i.MX7 SOC implementation.
  hw/arm: Move virt's PSCI DT fixup code to arm/boot.c
  Implement support for i.MX7 Sabre board

 default-configs/arm-softmmu.mak  |   3 +
 hw/arm/Makefile.objs |   5 +-
 hw/arm/boot.c|  65 
 hw/arm/coresight.c   | 120 
 hw/arm/fsl-imx6.c|   2 +-
 hw/arm/fsl-imx7.c| 583 
 hw/arm/mcimx7d-sabre.c   |  90 ++
 hw/arm/virt.c|  61 
 hw/intc/Makefile.objs|   2 +-
 hw/intc/imx_gpcv2.c  | 125 
 hw/misc/Makefile.objs|   4 +
 hw/misc/imx2_wdt.c   |  89 ++
 hw/misc/imx7_ccm.c   | 277 ++
 hw/misc/imx7_gpr.c   | 119 
 hw/misc/imx7_snvs.c  |  83 ++
 hw/pci-host/Makefile.objs|   2 +
 hw/pci-host/designware.c | 618 +++
 hw/sd/sdhci-internal.h   |  19 ++
 hw/sd/sdhci.c| 228 ++-
 hw/timer/imx_gpt.c   |  25 ++
 hw/usb/Makefile.objs |   1 +
 hw/usb/chipidea.c| 176 +++
 include/hw/arm/coresight.h   |  24 ++
 include/hw/arm/fsl-imx7.h| 223 ++
 include/hw/intc/imx_gpcv2.h  |  22 ++
 include/hw/misc/imx2_wdt.h   |  33 +++
 include/hw/misc/imx7_ccm.h   | 139 +
 include/hw/misc/imx7_gpr.h   |  28 ++
 include/hw/misc/imx7_snvs.h  |  35 +++
 include/hw/pci-host/designware.h |  93 ++
 include/hw/pci/pci_ids.h |   2 +
 include/hw/sd/sdhci

[Qemu-devel] [PATCH v4 02/14] hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC

2018-01-15 Thread Andrey Smirnov
Convert i.MX6 to use TYPE_IMX_USDHC since that's what real HW comes
with.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/arm/fsl-imx6.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index b0d4088290..e6559a8b12 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -93,7 +93,7 @@ static void fsl_imx6_init(Object *obj)
 }
 
 for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
-object_initialize(>esdhc[i], sizeof(s->esdhc[i]), 
TYPE_SYSBUS_SDHCI);
+object_initialize(>esdhc[i], sizeof(s->esdhc[i]), TYPE_IMX_USDHC);
 qdev_set_parent_bus(DEVICE(>esdhc[i]), sysbus_get_default());
 snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
 object_property_add_child(obj, name, OBJECT(>esdhc[i]), NULL);
-- 
2.14.3




[Qemu-devel] [PATCH v3 08/11] imx_fec: Add support for multiple Tx DMA rings

2018-01-02 Thread Andrey Smirnov
More recent version of the IP block support more than one Tx DMA ring,
so add the code implementing that feature.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 133 ---
 include/hw/net/imx_fec.h |  18 ++-
 2 files changed, 130 insertions(+), 21 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 825c879a28..77d27f763e 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -196,6 +196,31 @@ static const char *imx_eth_reg_name(IMXFECState *s, 
uint32_t index)
 }
 }
 
+/*
+ * Versions of this device with more than one TX descriptor save the
+ * 2nd and 3rd descriptors in a subsection, to maintain migration
+ * compatibility with previous versions of the device that only
+ * supported a single descriptor.
+ */
+static bool imx_eth_is_multi_tx_ring(void *opaque)
+{
+IMXFECState *s = IMX_FEC(opaque);
+
+return s->tx_ring_num > 1;
+}
+
+static const VMStateDescription vmstate_imx_eth_txdescs = {
+.name = "imx.fec/txdescs",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = imx_eth_is_multi_tx_ring,
+.fields = (VMStateField[]) {
+ VMSTATE_UINT32(tx_descriptor[1], IMXFECState),
+ VMSTATE_UINT32(tx_descriptor[2], IMXFECState),
+ VMSTATE_END_OF_LIST()
+}
+};
+
 static const VMStateDescription vmstate_imx_eth = {
 .name = TYPE_IMX_FEC,
 .version_id = 2,
@@ -203,15 +228,18 @@ static const VMStateDescription vmstate_imx_eth = {
 .fields = (VMStateField[]) {
 VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
 VMSTATE_UINT32(rx_descriptor, IMXFECState),
-VMSTATE_UINT32(tx_descriptor, IMXFECState),
-
+VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
 VMSTATE_UINT32(phy_status, IMXFECState),
 VMSTATE_UINT32(phy_control, IMXFECState),
 VMSTATE_UINT32(phy_advertise, IMXFECState),
 VMSTATE_UINT32(phy_int, IMXFECState),
 VMSTATE_UINT32(phy_int_mask, IMXFECState),
 VMSTATE_END_OF_LIST()
-}
+},
+.subsections = (const VMStateDescription * []) {
+_imx_eth_txdescs,
+NULL
+},
 };
 
 #define PHY_INT_ENERGYON(1 << 7)
@@ -406,7 +434,7 @@ static void imx_fec_do_tx(IMXFECState *s)
 {
 int frame_size = 0, descnt = 0;
 uint8_t *ptr = s->frame;
-uint32_t addr = s->tx_descriptor;
+uint32_t addr = s->tx_descriptor[0];
 
 while (descnt++ < IMX_MAX_DESC) {
 IMXFECBufDesc bd;
@@ -447,16 +475,47 @@ static void imx_fec_do_tx(IMXFECState *s)
 }
 }
 
-s->tx_descriptor = addr;
+s->tx_descriptor[0] = addr;
 
 imx_eth_update(s);
 }
 
-static void imx_enet_do_tx(IMXFECState *s)
+static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
 {
 int frame_size = 0, descnt = 0;
+
 uint8_t *ptr = s->frame;
-uint32_t addr = s->tx_descriptor;
+uint32_t addr, int_txb, int_txf, tdsr;
+size_t ring;
+
+switch (index) {
+case ENET_TDAR:
+ring= 0;
+int_txb = ENET_INT_TXB;
+int_txf = ENET_INT_TXF;
+tdsr= ENET_TDSR;
+break;
+case ENET_TDAR1:
+ring= 1;
+int_txb = ENET_INT_TXB1;
+int_txf = ENET_INT_TXF1;
+tdsr= ENET_TDSR1;
+break;
+case ENET_TDAR2:
+ring= 2;
+int_txb = ENET_INT_TXB2;
+int_txf = ENET_INT_TXF2;
+tdsr= ENET_TDSR2;
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: bogus value for index %x\n",
+  __func__, index);
+abort();
+break;
+}
+
+addr = s->tx_descriptor[ring];
 
 while (descnt++ < IMX_MAX_DESC) {
 IMXENETBufDesc bd;
@@ -502,32 +561,32 @@ static void imx_enet_do_tx(IMXFECState *s)
 
 frame_size = 0;
 if (bd.option & ENET_BD_TX_INT) {
-s->regs[ENET_EIR] |= ENET_INT_TXF;
+s->regs[ENET_EIR] |= int_txf;
 }
 }
 if (bd.option & ENET_BD_TX_INT) {
-s->regs[ENET_EIR] |= ENET_INT_TXB;
+s->regs[ENET_EIR] |= int_txb;
 }
 bd.flags &= ~ENET_BD_R;
 /* Write back the modified descriptor.  */
 imx_enet_write_bd(, addr);
 /* Advance to the next descriptor.  */
 if ((bd.flags & ENET_BD_W) != 0) {
-addr = s->regs[ENET_TDSR];
+addr = s->regs[tdsr];
 } else {
 addr += sizeof(bd);
 }
 }
 
-s->tx_descriptor = addr;
+s->tx_descriptor[ring] = addr;

[Qemu-devel] [PATCH v3 11/11] imx_fec: Reserve full FSL_IMX25_FEC_SIZE page for the register file

2018-01-02 Thread Andrey Smirnov
Some i.MX SoCs (e.g. i.MX7) have FEC registers going as far as offset
0x614, so to avoid getting aborts when accessing those on QEMU, extend
the register file to cover FSL_IMX25_FEC_SIZE(16K) of address space
instead of just 1K.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c   | 2 +-
 include/hw/arm/fsl-imx25.h | 1 -
 include/hw/net/imx_fec.h   | 1 +
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index c1cf7f9c58..4fb48f62ba 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1281,7 +1281,7 @@ static void imx_eth_realize(DeviceState *dev, Error 
**errp)
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
 memory_region_init_io(>iomem, OBJECT(dev), _eth_ops, s,
-  TYPE_IMX_FEC, 0x400);
+  TYPE_IMX_FEC, FSL_IMX25_FEC_SIZE);
 sysbus_init_mmio(sbd, >iomem);
 sysbus_init_irq(sbd, >irq[0]);
 sysbus_init_irq(sbd, >irq[1]);
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
index d0e8e9d956..65a73714ef 100644
--- a/include/hw/arm/fsl-imx25.h
+++ b/include/hw/arm/fsl-imx25.h
@@ -192,7 +192,6 @@ typedef struct FslIMX25State {
 #define FSL_IMX25_UART5_ADDR0x5002C000
 #define FSL_IMX25_UART5_SIZE0x4000
 #define FSL_IMX25_FEC_ADDR  0x50038000
-#define FSL_IMX25_FEC_SIZE  0x4000
 #define FSL_IMX25_CCM_ADDR  0x53F8
 #define FSL_IMX25_CCM_SIZE  0x4000
 #define FSL_IMX25_GPT4_ADDR 0x53F84000
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
index 91ef8f89a6..7b3faa4019 100644
--- a/include/hw/net/imx_fec.h
+++ b/include/hw/net/imx_fec.h
@@ -245,6 +245,7 @@ typedef struct {
 
 #define ENET_TX_RING_NUM   3
 
+#define FSL_IMX25_FEC_SIZE  0x4000
 
 typedef struct IMXFECState {
 /*< private >*/
-- 
2.14.3




[Qemu-devel] [PATCH v3 07/11] imx_fec: Emulate SHIFT16 in ENETx_RACC

2018-01-02 Thread Andrey Smirnov
Needed to support latest Linux kernel driver which relies on that
functionality.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 23 +++
 include/hw/net/imx_fec.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 6feda18742..825c879a28 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1037,6 +1037,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
 uint8_t *crc_ptr;
 unsigned int buf_len;
 size_t size = len;
+bool shift16 = s->regs[ENET_RACC] & ENET_RACC_SHIFT16;
 
 FEC_PRINTF("len %d\n", (int)size);
 
@@ -1051,6 +1052,10 @@ static ssize_t imx_enet_receive(NetClientState *nc, 
const uint8_t *buf,
 crc = cpu_to_be32(crc32(~0, buf, size));
 crc_ptr = (uint8_t *) 
 
+if (shift16) {
+size += 2;
+}
+
 /* Huge frames are truncted.  */
 if (size > s->regs[ENET_FTRL]) {
 size = s->regs[ENET_FTRL];
@@ -1087,6 +1092,24 @@ static ssize_t imx_enet_receive(NetClientState *nc, 
const uint8_t *buf,
 buf_len += size - 4;
 }
 buf_addr = bd.data;
+
+if (shift16) {
+/*
+ * If SHIFT16 bit of ENETx_RACC register is set we need to
+ * align the payload to 4-byte boundary.
+ */
+const uint8_t zeros[2] = { 0 };
+
+dma_memory_write(_space_memory, buf_addr,
+ zeros, sizeof(zeros));
+
+buf_addr += sizeof(zeros);
+buf_len  -= sizeof(zeros);
+
+/* We only do this once per Ethernet frame */
+shift16 = false;
+}
+
 dma_memory_write(_space_memory, buf_addr, buf, buf_len);
 buf += buf_len;
 if (size < 4) {
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
index a390d704a6..af0840a0fa 100644
--- a/include/hw/net/imx_fec.h
+++ b/include/hw/net/imx_fec.h
@@ -170,6 +170,8 @@
 #define ENET_TWFR_TFWR_LENGTH  (6)
 #define ENET_TWFR_STRFWD   (1 << 8)
 
+#define ENET_RACC_SHIFT16  BIT(7)
+
 /* Buffer Descriptor.  */
 typedef struct {
 uint16_t length;
-- 
2.14.3




[Qemu-devel] [PATCH v3 10/11] imx_fec: Fix a typo in imx_enet_receive()

2018-01-02 Thread Andrey Smirnov
Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 6cb9e2e20e..c1cf7f9c58 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1150,7 +1150,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
 size += 2;
 }
 
-/* Huge frames are truncted.  */
+/* Huge frames are truncated. */
 if (size > s->regs[ENET_FTRL]) {
 size = s->regs[ENET_FTRL];
 flags |= ENET_BD_TR | ENET_BD_LG;
-- 
2.14.3




[Qemu-devel] [PATCH v3 09/11] imx_fec: Use correct length for packet size

2018-01-02 Thread Andrey Smirnov
Use 'frame_size' instead of 'len' when calling qemu_send_packet(),
failing to do so results in malformed packets send in case when that
packed is fragmented into multiple DMA transactions.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 77d27f763e..6cb9e2e20e 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -556,7 +556,7 @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
 }
 /* Last buffer in frame.  */
 
-qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
+qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
 ptr = s->frame;
 
 frame_size = 0;
-- 
2.14.3




[Qemu-devel] [PATCH v3 05/11] imx_fec: Use ENET_FTRL to determine truncation length

2018-01-02 Thread Andrey Smirnov
Frame truncation length, TRUNC_FL, is determined by the contents of
ENET_FTRL register, so convert the code to use it instead of a
hardcoded constant.

To avoid the case where TRUNC_FL is greater that ENET_MAX_FRAME_SIZE,
increase the value of the latter to its theoretical maximum of 16K.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 4 ++--
 include/hw/net/imx_fec.h | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 56cb72273c..50da91bf9e 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1052,8 +1052,8 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
 crc_ptr = (uint8_t *) 
 
 /* Huge frames are truncted.  */
-if (size > ENET_MAX_FRAME_SIZE) {
-size = ENET_MAX_FRAME_SIZE;
+if (size > s->regs[ENET_FTRL]) {
+size = s->regs[ENET_FTRL];
 flags |= ENET_BD_TR | ENET_BD_LG;
 }
 
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
index 67993870a2..a390d704a6 100644
--- a/include/hw/net/imx_fec.h
+++ b/include/hw/net/imx_fec.h
@@ -86,7 +86,6 @@
 #define ENET_TCCR3 393
 #define ENET_MAX   400
 
-#define ENET_MAX_FRAME_SIZE2032
 
 /* EIR and EIMR */
 #define ENET_INT_HB(1 << 31)
@@ -155,6 +154,8 @@
 #define ENET_RCR_NLC   (1 << 30)
 #define ENET_RCR_GRS   (1 << 31)
 
+#define ENET_MAX_FRAME_SIZE(1 << ENET_RCR_MAX_FL_LENGTH)
+
 /* TCR */
 #define ENET_TCR_GTS   (1 << 0)
 #define ENET_TCR_FDEN  (1 << 2)
-- 
2.14.3




[Qemu-devel] [PATCH v3 00/11] i.MX FEC changes

2018-01-02 Thread Andrey Smirnov
Hi everyone,

This patchset is v3 of a spin-off from original i.MX7 support submission
found here [1], containing all of the patchest that are more or less
agreed upon and are ready (hopefully!) for inclusion.

Changes since [v2]:

- All SD related patches are dropped from this series (to be
  re-submitted once Philippe's work lands upstream). Note that
  "Implement write method of ACMD12ERRSTS register" has been
  incorporated into Philippe's submission

- Collected Reviewed-by for patch 2 from Philippe

Changes since [v1]:

- Collected Reviewed-by tags from Peter

- Implemented forgotten feedback from Peter for
  "sdhci: Add i.MX specific subtype of SDHCI"

- "imx_fec: Move Tx frame buffer away from the stack" sent out
  properly (fingers crossed)

- Added trivial patch to swith i.MX6 over to TYPE_IMX_USDHC

- Added "sd: Check for READ_MULTIPLE_BLOCK size limit
  violation first" to address a small problem I was seeing
  when tesiting SD against latest vanilla kernel

Changes since [1]:

- Rx buffer in FEC was moved from stack to heap to allow
  worry-free expansion to 16K limit.

- Added more comments explaining rather convoluted bit-moving
  in eSHDC emuation code

- Triple Tx ring DMA "VMState" code was changed to follow
  Peter's recommendations (avoiding the need to incrememnt the
  version_id)

- FSL_IMX25_FEC_SIZE is used as a size of FEC's register file

- Removed leftover code from "imx_fec: Change queue flushing
  heuristics"

[v2] https://lists.gnu.org/archive/html/qemu-arm/2017-12/msg00175.html
[v1] https://lists.gnu.org/archive/html/qemu-arm/2017-12/msg00085.html
[1]  https://lists.gnu.org/archive/html/qemu-arm/2017-11/msg00045.html


Andrey Smirnov (11):
  imx_fec: Do not link to netdev
  imx_fec: Refactor imx_eth_enable_rx()
  imx_fec: Change queue flushing heuristics
  imx_fec: Move Tx frame buffer away from the stack
  imx_fec: Use ENET_FTRL to determine truncation length
  imx_fec: Use MIN instead of explicit ternary operator
  imx_fec: Emulate SHIFT16 in ENETx_RACC
  imx_fec: Add support for multiple Tx DMA rings
  imx_fec: Use correct length for packet size
  imx_fec: Fix a typo in imx_enet_receive()
  imx_fec: Reserve full FSL_IMX25_FEC_SIZE page for the register file

 hw/arm/fsl-imx6.c  |   1 +
 hw/net/imx_fec.c   | 210 +++--
 include/hw/arm/fsl-imx25.h |   1 -
 include/hw/net/imx_fec.h   |  27 +-
 4 files changed, 188 insertions(+), 51 deletions(-)

-- 
2.14.3




[Qemu-devel] [PATCH v3 01/11] imx_fec: Do not link to netdev

2018-01-02 Thread Andrey Smirnov
Binding to a particular netdev doesn't seem to belong to this layer
and should probably be done as a part of board or SoC specific code.

Convert all of the users of this IP block to use
qdev_set_nic_properties() instead.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/arm/fsl-imx6.c | 1 +
 hw/net/imx_fec.c  | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 59ef33efa9..b0d4088290 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -385,6 +385,7 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
 spi_table[i].irq));
 }
 
+qdev_set_nic_properties(DEVICE(>eth), _table[0]);
 object_property_set_bool(OBJECT(>eth), true, "realized", );
 if (err) {
 error_propagate(errp, err);
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 90e6ee35ba..88b4b049d7 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1171,8 +1171,6 @@ static void imx_eth_realize(DeviceState *dev, Error 
**errp)
 
 qemu_macaddr_default_if_unset(>conf.macaddr);
 
-s->conf.peers.ncs[0] = nd_table[0].netdev;
-
 s->nic = qemu_new_nic(_eth_net_info, >conf,
   object_get_typename(OBJECT(dev)),
   DEVICE(dev)->id, s);
-- 
2.14.3




[Qemu-devel] [PATCH v3 06/11] imx_fec: Use MIN instead of explicit ternary operator

2018-01-02 Thread Andrey Smirnov
Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 50da91bf9e..6feda18742 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1076,7 +1076,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
   TYPE_IMX_FEC, __func__);
 break;
 }
-buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
+buf_len = MIN(size, s->regs[ENET_MRBR]);
 bd.length = buf_len;
 size -= buf_len;
 
-- 
2.14.3




[Qemu-devel] [PATCH v3 03/11] imx_fec: Change queue flushing heuristics

2018-01-02 Thread Andrey Smirnov
In current implementation, packet queue flushing logic seem to suffer
from a deadlock like scenario if a packet is received by the interface
before before Rx ring is initialized by Guest's driver. Consider the
following sequence of events:

1. A QEMU instance is started against a TAP device on Linux
   host, running Linux guest, e. g., something to the effect
   of:

   qemu-system-arm \
  -net nic,model=imx.fec,netdev=lan0 \
  netdev tap,id=lan0,ifname=tap0,script=no,downscript=no \
  ... rest of the arguments ...

2. Once QEMU starts, but before guest reaches the point where
   FEC deriver is done initializing the HW, Guest, via TAP
   interface, receives a number of multicast MDNS packets from
   Host (not necessarily true for every OS, but it happens at
   least on Fedora 25)

3. Recieving a packet in such a state results in
   imx_eth_can_receive() returning '0', which in turn causes
   tap_send() to disable corresponding event (tap.c:203)

4. Once Guest's driver reaches the point where it is ready to
   recieve packets it prepares Rx ring descriptors and writes
   ENET_RDAR_RDAR to ENET_RDAR register to indicate to HW that
   more descriptors are ready. And at this points emulation
   layer does this:

 s->regs[index] = ENET_RDAR_RDAR;
 imx_eth_enable_rx(s);

   which, combined with:

  if (!s->regs[ENET_RDAR]) {
 qemu_flush_queued_packets(qemu_get_queue(s->nic));
  }

   results in Rx queue never being flushed and corresponding
   I/O event beign disabled.

To prevent the problem, change the code to always flush packet queue
when ENET_RDAR transitions 0 -> ENET_RDAR_RDAR.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 8b2e4b8ffe..eb034ffd0c 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -533,7 +533,7 @@ static void imx_eth_do_tx(IMXFECState *s)
 }
 }
 
-static void imx_eth_enable_rx(IMXFECState *s)
+static void imx_eth_enable_rx(IMXFECState *s, bool flush)
 {
 IMXFECBufDesc bd;
 bool rx_ring_full;
@@ -544,7 +544,7 @@ static void imx_eth_enable_rx(IMXFECState *s)
 
 if (rx_ring_full) {
 FEC_PRINTF("RX buffer full\n");
-} else if (!s->regs[ENET_RDAR]) {
+} else if (flush) {
 qemu_flush_queued_packets(qemu_get_queue(s->nic));
 }
 
@@ -807,7 +807,7 @@ static void imx_eth_write(void *opaque, hwaddr offset, 
uint64_t value,
 if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
 if (!s->regs[index]) {
 s->regs[index] = ENET_RDAR_RDAR;
-imx_eth_enable_rx(s);
+imx_eth_enable_rx(s, true);
 }
 } else {
 s->regs[index] = 0;
@@ -930,7 +930,7 @@ static int imx_eth_can_receive(NetClientState *nc)
 
 FEC_PRINTF("\n");
 
-return s->regs[ENET_RDAR] ? 1 : 0;
+return !!s->regs[ENET_RDAR];
 }
 
 static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
@@ -1020,7 +1020,7 @@ static ssize_t imx_fec_receive(NetClientState *nc, const 
uint8_t *buf,
 }
 }
 s->rx_descriptor = addr;
-imx_eth_enable_rx(s);
+imx_eth_enable_rx(s, false);
 imx_eth_update(s);
 return len;
 }
@@ -1116,7 +1116,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
 }
 }
 s->rx_descriptor = addr;
-imx_eth_enable_rx(s);
+imx_eth_enable_rx(s, false);
 imx_eth_update(s);
 return len;
 }
-- 
2.14.3




[Qemu-devel] [PATCH v3 04/11] imx_fec: Move Tx frame buffer away from the stack

2018-01-02 Thread Andrey Smirnov
Make Tx frame assembly buffer to be a paort of IMXFECState structure
to avoid a concern about having large data buffer on the stack.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 22 +++---
 include/hw/net/imx_fec.h |  3 +++
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index eb034ffd0c..56cb72273c 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -405,8 +405,7 @@ static void imx_eth_update(IMXFECState *s)
 static void imx_fec_do_tx(IMXFECState *s)
 {
 int frame_size = 0, descnt = 0;
-uint8_t frame[ENET_MAX_FRAME_SIZE];
-uint8_t *ptr = frame;
+uint8_t *ptr = s->frame;
 uint32_t addr = s->tx_descriptor;
 
 while (descnt++ < IMX_MAX_DESC) {
@@ -431,8 +430,8 @@ static void imx_fec_do_tx(IMXFECState *s)
 frame_size += len;
 if (bd.flags & ENET_BD_L) {
 /* Last buffer in frame.  */
-qemu_send_packet(qemu_get_queue(s->nic), frame, frame_size);
-ptr = frame;
+qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
+ptr = s->frame;
 frame_size = 0;
 s->regs[ENET_EIR] |= ENET_INT_TXF;
 }
@@ -456,8 +455,7 @@ static void imx_fec_do_tx(IMXFECState *s)
 static void imx_enet_do_tx(IMXFECState *s)
 {
 int frame_size = 0, descnt = 0;
-uint8_t frame[ENET_MAX_FRAME_SIZE];
-uint8_t *ptr = frame;
+uint8_t *ptr = s->frame;
 uint32_t addr = s->tx_descriptor;
 
 while (descnt++ < IMX_MAX_DESC) {
@@ -482,13 +480,13 @@ static void imx_enet_do_tx(IMXFECState *s)
 frame_size += len;
 if (bd.flags & ENET_BD_L) {
 if (bd.option & ENET_BD_PINS) {
-struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
+struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
 if (IP_HEADER_VERSION(ip_hd) == 4) {
-net_checksum_calculate(frame, frame_size);
+net_checksum_calculate(s->frame, frame_size);
 }
 }
 if (bd.option & ENET_BD_IINS) {
-struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
+struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
 /* We compute checksum only for IPv4 frames */
 if (IP_HEADER_VERSION(ip_hd) == 4) {
 uint16_t csum;
@@ -498,8 +496,10 @@ static void imx_enet_do_tx(IMXFECState *s)
 }
 }
 /* Last buffer in frame.  */
-qemu_send_packet(qemu_get_queue(s->nic), frame, len);
-ptr = frame;
+
+qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
+ptr = s->frame;
+
 frame_size = 0;
 if (bd.option & ENET_BD_TX_INT) {
 s->regs[ENET_EIR] |= ENET_INT_TXF;
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
index 62ad473b05..67993870a2 100644
--- a/include/hw/net/imx_fec.h
+++ b/include/hw/net/imx_fec.h
@@ -252,6 +252,9 @@ typedef struct IMXFECState {
 uint32_t phy_int_mask;
 
 bool is_fec;
+
+/* Buffer used to assemble a Tx frame */
+uint8_t frame[ENET_MAX_FRAME_SIZE];
 } IMXFECState;
 
 #endif
-- 
2.14.3




[Qemu-devel] [PATCH v3 02/11] imx_fec: Refactor imx_eth_enable_rx()

2018-01-02 Thread Andrey Smirnov
Refactor imx_eth_enable_rx() to have more meaningfull variable name
than 'tmp' and to reduce number of logical negations done.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org>
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 88b4b049d7..8b2e4b8ffe 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -536,19 +536,19 @@ static void imx_eth_do_tx(IMXFECState *s)
 static void imx_eth_enable_rx(IMXFECState *s)
 {
 IMXFECBufDesc bd;
-bool tmp;
+bool rx_ring_full;
 
 imx_fec_read_bd(, s->rx_descriptor);
 
-tmp = ((bd.flags & ENET_BD_E) != 0);
+rx_ring_full = !(bd.flags & ENET_BD_E);
 
-if (!tmp) {
+if (rx_ring_full) {
 FEC_PRINTF("RX buffer full\n");
 } else if (!s->regs[ENET_RDAR]) {
 qemu_flush_queued_packets(qemu_get_queue(s->nic));
 }
 
-s->regs[ENET_RDAR] = tmp ? ENET_RDAR_RDAR : 0;
+s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
 }
 
 static void imx_eth_reset(DeviceState *d)
-- 
2.14.3




Re: [Qemu-devel] [PATCH v2 05/15] imx_fec: Use ENET_FTRL to determine truncation length

2017-12-16 Thread Andrey Smirnov
On Fri, Dec 15, 2017 at 2:15 AM, Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> Hi Andrey,
>
> On 12/14/2017 11:52 AM, Andrey Smirnov wrote:
>> Frame truncation length, TRUNC_FL, is determined by the contents of
>> ENET_FTRL register, so convert the code to use it instead of a
>> hardcoded constant.
>>
>> To avoid the case where TRUNC_FL is greater that ENET_MAX_FRAME_SIZE,
>> increase the value of the latter to its theoretical maximum of 16K.
>>
>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.org
>> Cc: yurov...@gmail.com
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> ---
>>  hw/net/imx_fec.c | 4 ++--
>>  include/hw/net/imx_fec.h | 3 ++-
>>  2 files changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
>> index 56cb72273c..50da91bf9e 100644
>> --- a/hw/net/imx_fec.c
>> +++ b/hw/net/imx_fec.c
>> @@ -1052,8 +1052,8 @@ static ssize_t imx_enet_receive(NetClientState *nc, 
>> const uint8_t *buf,
>>  crc_ptr = (uint8_t *) 
>>
>>  /* Huge frames are truncted.  */
>> -if (size > ENET_MAX_FRAME_SIZE) {
>> -size = ENET_MAX_FRAME_SIZE;
>> +if (size > s->regs[ENET_FTRL]) {
>
> Shouldn't this be:
>
>if (size > s->regs[ENET_FTRL] + 1) {
>
>> +size = s->regs[ENET_FTRL];
>
> and:
>
>size = s->regs[ENET_FTRL] + 1;
>

I haven't tried to reproduce this in real HW and verify the behavior,
so I can't say for a fact, but the datasheet seems to be pretty clear
about "ENETx_FTRL":

"Frame Truncation Length
Indicates the value a receive frame is truncated, if it is greater
than this value. Must be greater than or
equal to RCR[MAX_FL].
NOTE: Truncation happens at TRUNC_FL. However, when truncation occurs,
the application (FIFO) may
receive less data, guaranteeing that it never receives more than the set limit."

so, having nothing better to go on than above description, I think the
original code is OK.


>>  flags |= ENET_BD_TR | ENET_BD_LG;
>>  }
>>
>> diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
>> index 67993870a2..a390d704a6 100644
>> --- a/include/hw/net/imx_fec.h
>> +++ b/include/hw/net/imx_fec.h
>> @@ -86,7 +86,6 @@
>>  #define ENET_TCCR3 393
>>  #define ENET_MAX   400
>>
>> -#define ENET_MAX_FRAME_SIZE2032
>>
>>  /* EIR and EIMR */
>>  #define ENET_INT_HB(1 << 31)
>> @@ -155,6 +154,8 @@
>>  #define ENET_RCR_NLC   (1 << 30)
>>  #define ENET_RCR_GRS   (1 << 31)
>>
>> +#define ENET_MAX_FRAME_SIZE(1 << ENET_RCR_MAX_FL_LENGTH)
>> +
>>  /* TCR */
>>  #define ENET_TCR_GTS   (1 << 0)
>>  #define ENET_TCR_FDEN  (1 << 2)
>>



Re: [Qemu-devel] [PATCH] hw/misc: Add code to emulate PFUZE3000 PMIC

2017-12-16 Thread Andrey Smirnov
On Sat, Dec 16, 2017 at 5:41 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:
> On 15 December 2017 at 19:21, Andrey Smirnov <andrew.smir...@gmail.com> wrote:
>> On Fri, Dec 15, 2017 at 6:56 AM, Peter Maydell <peter.mayd...@linaro.org> 
>> wrote:
>>> Is there a board which needs this device? We usually
>>> only add devices together with whatever's using them.
>
>> It's a pretty popular PMIC used on majority on i.MX reference designs,
>> but I am not sure how many of those boards truly need it in QEMU. I
>> ended up having to implement this code for a custom i.MX7 board that
>> used one of PFUZE3000's output as a power supply for USB. I am not
>> sure if I'm ever going to submit patches for that mystery board
>> upstream. Looking at imx6qdl-sabresd.dtsi, in Linux source tree I
>> think this emulation code would also be needed for USB emulation on
>> i.MX6 SabreSD board, but I haven't verified it in practice.
>>
>> Is this enough of a case to justify the patch's inclusion, or should I
>> go back and find a board QEMU supports that actually needs this
>> (either answer is perfectly fine with me)?
>
> I think what I'd like to see is some board model in QEMU
> actually creating this device. (I assume it's not intended
> as a "user creates it with -device" pluggable device.)
> Otherwise it's just dead code from upstream's point of view.
>

Your assumption is correct and fair enough, I'll see if I can find a
place upstream it can be put it.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v2 12/15] sdhci: Add i.MX specific subtype of SDHCI

2017-12-16 Thread Andrey Smirnov
On Fri, Dec 15, 2017 at 12:15 PM, Philippe Mathieu-Daudé
<f4...@amsat.org> wrote:
> Hi Andrey,
>
>>> I rather disagree with this patch, however I applied it on top of my
>>> current tree and plan to refactor it. But if it is applied before, I can
>>> survive :) Not a strong NACK.
>>>
>>
>> Umm, Philippe, I didn't really ask you to refactor my code and I'd
>> really appreciate if you'd engage into a proper review process with me
>> on this patch, instead of just telling me "I don't like the code, but,
>> worry not, I'll bulldoze it away later anyway".
>
> Hey I'm sorry I didn't meant to be rude... reading my comment back I
> don't find it offensive, so we might have english-proxy misunderstanding.
>
> I posted a few series doing quite a lot of modifications in the SDHCI
> code, and instead of having a race "the first merged, the second has
> figure out himself" I offered to rework this patch on top of my series
> and send it to you so you can test it.
>
> I don't plan to 'bulldoze' it, there is no sens because I don't have all
> your setups to test it, I just suggested to 'refactor' it to avoid merge
> conflicts and head-aches.
>
> By "But if it is applied before, I can survive" I meant:
> "if it is applied before [my series get merged], I can survive [to adapt
> my series to fix the resulting merge conflicts]"
>

OK, gotcha. I think it would be the easiest for both of us to let your
work get merged first, since you patch is extensive and would warrant
me re-testing i.MX stuff anyway.
So how about this: I'll pull i.MX uSDHC patch back into original i.MX7
submission and by the time it is ready to be merged in, your code will
hopefully be in the master already, sounds good?

Meanwhile, do you have public git URL for your changes that I can use
to re-base on top of?


>>> On 12/14/2017 11:52 AM, Andrey Smirnov wrote:
>>>> IP block found on several generations of i.MX family does not use
>>>> vanilla SDHCI implementation and it comes with a number of quirks.
>>>>
>>>> Introduce i.MX SDHCI subtype of SDHCI block to add code necessary to
>>>> support unmodified Linux guest driver.
>>>>
>>>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>>>> Cc: Jason Wang <jasow...@redhat.com>
>>>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>>>> Cc: qemu-devel@nongnu.org
>>>> Cc: qemu-...@nongnu.org
>>>> Cc: yurov...@gmail.com
>>>> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
>>>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>>>> ---
>>>>  hw/sd/sdhci-internal.h |  19 +
>>>>  hw/sd/sdhci.c  | 228 
>>>> -
>>>>  include/hw/sd/sdhci.h  |  14 +++
>>>>  3 files changed, 259 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
>>>> index 161177cf39..b86ac0791b 100644
>>>> --- a/hw/sd/sdhci-internal.h
>>>> +++ b/hw/sd/sdhci-internal.h
>>>> @@ -85,12 +85,18 @@
>>>>
>>>>  /* R/W Host control Register 0x0 */
>>>>  #define SDHC_HOSTCTL   0x28
>>>> +#define SDHC_CTRL_LED  0x01
>>>>  #define SDHC_CTRL_DMA_CHECK_MASK   0x18
>>>>  #define SDHC_CTRL_SDMA 0x00
>>>>  #define SDHC_CTRL_ADMA1_32 0x08
>>>>  #define SDHC_CTRL_ADMA2_32 0x10
>>>>  #define SDHC_CTRL_ADMA2_64 0x18
>>>>  #define SDHC_DMA_TYPE(x)   ((x) & SDHC_CTRL_DMA_CHECK_MASK)
>>>> +#define SDHC_CTRL_4BITBUS  0x02
>>>> +#define SDHC_CTRL_8BITBUS  0x20
>>>> +#define SDHC_CTRL_CDTEST_INS   0x40
>>>> +#define SDHC_CTRL_CDTEST_EN0x80
>>>> +
>>>>
>>>>  /* R/W Power Control Register 0x0 */
>>>>  #define SDHC_PWRCON0x29
>>>> @@ -229,4 +235,17 @@ enum {
>>>>
>>>>  extern const VMStateDescription sdhci_vmstate;
>>>>
>>>> +
>>>> +#define ESDHC_MIX_CTRL  0x48
>>>> +#define ESDHC_VENDOR_SPEC   0xc0
>>>> +#define ESDHC_DLL_CTRL  0x60
>>>> +
>>>> +#define ESDHC_TUNING_CTRL   0xcc
>>>> +#define ESDHC_TUNE_CTRL_STATUS  0x68
>>>> +#define ESDHC_WTMK_LVL  0x44
>

Re: [Qemu-devel] [PATCH] hw/misc: Add code to emulate PFUZE3000 PMIC

2017-12-15 Thread Andrey Smirnov
On Fri, Dec 15, 2017 at 6:56 AM, Peter Maydell <peter.mayd...@linaro.org> wrote:
> On 14 December 2017 at 15:19, Andrey Smirnov <andrew.smir...@gmail.com> wrote:
>> Add trivial code to emulate PFUZE3000 PMIC.
>>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.orgn
>> Cc: yurov...@gmail.com
>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> ---
>>
>> Integrating this into a build system via "obj-y" might not be the best
>> way. Does this code need a dedicated CONFIG_ symbol?
>
> Yes, it ought to have a CONFIG_something symbol and be enabled
> via the whatever.mak for whatever guest architecture needs this
> device.
>
> Is there a board which needs this device? We usually
> only add devices together with whatever's using them.
>

It's a pretty popular PMIC used on majority on i.MX reference designs,
but I am not sure how many of those boards truly need it in QEMU. I
ended up having to implement this code for a custom i.MX7 board that
used one of PFUZE3000's output as a power supply for USB. I am not
sure if I'm ever going to submit patches for that mystery board
upstream. Looking at imx6qdl-sabresd.dtsi, in Linux source tree I
think this emulation code would also be needed for USB emulation on
i.MX6 SabreSD board, but I haven't verified it in practice.

Is this enough of a case to justify the patch's inclusion, or should I
go back and find a board QEMU supports that actually needs this
(either answer is perfectly fine with me)?

>> diff --git a/hw/misc/pfuze3000.c b/hw/misc/pfuze3000.c
>> new file mode 100644
>> index 00..f414b7c0ba
>> --- /dev/null
>> +++ b/hw/misc/pfuze3000.c
>> @@ -0,0 +1,212 @@
>> +/*
>> + *
>> + * Copyright (c) 2017, Impinj, Inc.
>> + *
>> + * Author: Andrey Smirnov <andrew.smir...@gmail.com>
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 or
>> + * (at your option) version 3 of the License.
>
> The .h file is "v2 or later", but the .c file is "v2 or v3".
> Is that an intentional difference? Generally we go with "v2 or later".
>

Nope, just me not paying attention. Will change in v2.

>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, see <http://www.gnu.org/licenses/>.
>> + */
>
>> +static void pfuze3000_reset(DeviceState *ds)
>> +{
>> +PFuze3000State *s = PFUZE3000(ds);
>> +
>> +s->reg = PFUZE100_INVAL;
>
> This function needs to reset all the device state
> (all the fields that the guest can modify).
>

Good point, will change in v2.

Thanks,
Andrey Smirnov



Re: [Qemu-devel] [PATCH v2 12/15] sdhci: Add i.MX specific subtype of SDHCI

2017-12-15 Thread Andrey Smirnov
On Thu, Dec 14, 2017 at 6:31 PM, Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> Hi Andrey, Peter.
>
> I rather disagree with this patch, however I applied it on top of my
> current tree and plan to refactor it. But if it is applied before, I can
> survive :) Not a strong NACK.
>

Umm, Philippe, I didn't really ask you to refactor my code and I'd
really appreciate if you'd engage into a proper review process with me
on this patch, instead of just telling me "I don't like the code, but,
worry not, I'll bulldoze it away later anyway".


> See comment inlined.
>
> On 12/14/2017 11:52 AM, Andrey Smirnov wrote:
>> IP block found on several generations of i.MX family does not use
>> vanilla SDHCI implementation and it comes with a number of quirks.
>>
>> Introduce i.MX SDHCI subtype of SDHCI block to add code necessary to
>> support unmodified Linux guest driver.
>>
>> Cc: Peter Maydell <peter.mayd...@linaro.org>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
>> Cc: qemu-devel@nongnu.org
>> Cc: qemu-...@nongnu.org
>> Cc: yurov...@gmail.com
>> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
>> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
>> ---
>>  hw/sd/sdhci-internal.h |  19 +
>>  hw/sd/sdhci.c  | 228 
>> -
>>  include/hw/sd/sdhci.h  |  14 +++
>>  3 files changed, 259 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
>> index 161177cf39..b86ac0791b 100644
>> --- a/hw/sd/sdhci-internal.h
>> +++ b/hw/sd/sdhci-internal.h
>> @@ -85,12 +85,18 @@
>>
>>  /* R/W Host control Register 0x0 */
>>  #define SDHC_HOSTCTL   0x28
>> +#define SDHC_CTRL_LED  0x01
>>  #define SDHC_CTRL_DMA_CHECK_MASK   0x18
>>  #define SDHC_CTRL_SDMA 0x00
>>  #define SDHC_CTRL_ADMA1_32 0x08
>>  #define SDHC_CTRL_ADMA2_32 0x10
>>  #define SDHC_CTRL_ADMA2_64 0x18
>>  #define SDHC_DMA_TYPE(x)   ((x) & SDHC_CTRL_DMA_CHECK_MASK)
>> +#define SDHC_CTRL_4BITBUS  0x02
>> +#define SDHC_CTRL_8BITBUS  0x20
>> +#define SDHC_CTRL_CDTEST_INS   0x40
>> +#define SDHC_CTRL_CDTEST_EN0x80
>> +
>>
>>  /* R/W Power Control Register 0x0 */
>>  #define SDHC_PWRCON0x29
>> @@ -229,4 +235,17 @@ enum {
>>
>>  extern const VMStateDescription sdhci_vmstate;
>>
>> +
>> +#define ESDHC_MIX_CTRL  0x48
>> +#define ESDHC_VENDOR_SPEC   0xc0
>> +#define ESDHC_DLL_CTRL  0x60
>> +
>> +#define ESDHC_TUNING_CTRL   0xcc
>> +#define ESDHC_TUNE_CTRL_STATUS  0x68
>> +#define ESDHC_WTMK_LVL  0x44
>> +
>> +#define ESDHC_CTRL_4BITBUS  (0x1 << 1)
>> +#define ESDHC_CTRL_8BITBUS  (0x2 << 1)
>> +
>> +
>>  #endif
>> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
>> index 6d6a791ee9..758af067f9 100644
>> --- a/hw/sd/sdhci.c
>> +++ b/hw/sd/sdhci.c
>> @@ -265,7 +265,8 @@ static void sdhci_send_command(SDHCIState *s)
>>  }
>>  }
>>
>> -if ((s->norintstsen & SDHC_NISEN_TRSCMP) &&
>> +if (!(s->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
>> +(s->norintstsen & SDHC_NISEN_TRSCMP) &&
>>  (s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
>>  s->norintsts |= SDHC_NIS_TRSCMP;
>>  }
>> @@ -1191,6 +1192,8 @@ static void sdhci_initfn(SDHCIState *s)
>>
>>  s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
>> sdhci_raise_insertion_irq, s);
>>  s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 
>> sdhci_data_transfer, s);
>> +
>> +s->io_ops = _mmio_ops;
>>  }
>>
>>  static void sdhci_uninitfn(SDHCIState *s)
>> @@ -1347,7 +1350,7 @@ static void sdhci_sysbus_realize(DeviceState *dev, 
>> Error ** errp)
>>  s->buf_maxsz = sdhci_get_fifolen(s);
>>  s->fifo_buffer = g_malloc0(s->buf_maxsz);
>>  sysbus_init_irq(sbd, >irq);
>> -memory_region_init_io(>iomem, OBJECT(s), _mmio_ops, s, "sdhci",
>> +memory_region_init_io(>iomem, OBJECT(s), s->io_ops, s, "sdhci",
>>  SDHC_REGISTERS_MAP_SIZE);
>> 

Re: [Qemu-devel] [PATCH v2 14/15] sd: Check for READ_MULTIPLE_BLOCK size limit violation first

2017-12-14 Thread Andrey Smirnov
On Thu, Dec 14, 2017 at 6:52 AM, Andrey Smirnov
<andrew.smir...@gmail.com> wrote:
> Check for READ_MULTIPLE_BLOCK size limit violation first as opposed to
> doing at the end of the command handler. Consider the following
> scenario:
>
> Emulated host driver is trying to read last byte of the last sector
> via CMD18/ADMA, so what would happen is the following:
>
> 1. "ret" is filled with desired byte and "sd->data_offset" is
>incremented to 512 by
>
> ret = sd->data[sd->data_offset ++];
>
> 2. sd->data_offset >= io_len becomes true, so
>
> sd->data_start += io_len;
>
>moves "sd->data_start" past valid data boundaries.
>
> 3. as a result "sd->data_start + io_len > sd->size" check becomes true
>and sd->card_status is marked with ADDRESS_ERROR, telling emulated
>host that the last CMD18 read failed, despite nothing bad/illegal
>happening.
>
> To avoid having this false positive, move out-of-bounds check to
> happen before BLK_READ_BLOCK(), so this way it will only trigger if
> illegal read is truly about to happen.
>

Disregard this patch, exactly this fix is already present in latest QEMU master.

Sorry for the noise.

Thanks,
Andrey Smirnov

> Cc: Peter Maydell <peter.mayd...@linaro.org>
> Cc: Jason Wang <jasow...@redhat.com>
> Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
> Cc: qemu-devel@nongnu.org
> Cc: qemu-...@nongnu.org
> Cc: yurov...@gmail.com
> Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
> ---
>  hw/sd/sd.c | 16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index ba47bff4db..ce4ef17be3 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1797,8 +1797,17 @@ uint8_t sd_read_data(SDState *sd)
>  break;
>
>  case 18:   /* CMD18:  READ_MULTIPLE_BLOCK */
> -if (sd->data_offset == 0)
> +if (sd->data_offset == 0) {
> +if (sd->data_start + io_len > sd->size) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: Trying to read past card's capacity\n",
> +  __func__);
> +sd->card_status |= ADDRESS_ERROR;
> +return 0x00;
> +}
> +
>  BLK_READ_BLOCK(sd->data_start, io_len);
> +}
>  ret = sd->data[sd->data_offset ++];
>
>  if (sd->data_offset >= io_len) {
> @@ -1812,11 +1821,6 @@ uint8_t sd_read_data(SDState *sd)
>  break;
>  }
>  }
> -
> -if (sd->data_start + io_len > sd->size) {
> -sd->card_status |= ADDRESS_ERROR;
> -break;
> -}
>  }
>  break;
>
> --
> 2.14.3
>



Re: [Qemu-devel] [PATCH 12/13] sdhci: Add i.MX specific subtype of SDHCI

2017-12-14 Thread Andrey Smirnov
On Thu, Dec 14, 2017 at 7:32 AM, Philippe Mathieu-Daudé <f4...@amsat.org> wrote:
> Hi Andrey,
>
> On 12/14/2017 11:03 AM, Andrey Smirnov wrote:
>> On Tue, Dec 12, 2017 at 9:52 AM, Peter Maydell <peter.mayd...@linaro.org> 
>> wrote:
>>> On 11 December 2017 at 21:30, Andrey Smirnov <andrew.smir...@gmail.com> 
>>> wrote:
> [...]
>>>> +case ESDHC_DLL_CTRL:
>>>> +case ESDHC_TUNE_CTRL_STATUS:
>>>> +case 0x6c:
>>>
>>> Isn't there a name we can give 0x6c ?
>>>
>>
>> Unfortunately, not that I know of. It's a mystery register not listed
>> in RM and the only place I can found it being mentioned is in Linux
>> driver as a part of errata ESDHC_FLAG_ERR004536 fix, where it is used
>> nameless as well.
>
> This sets the SD CLK/RCLK frequency (10-bit) for the 104MB/sec bus speed
> (UHS-I mode).
>
> The "Sampling Clock Tuning Procedure" figure in the Spec v3 is helpful.
>

I am a bit hesitant to agree that this is indeed the case. ERR004536
errata's title is "uSDHC: ADMA Length Mismatch Error may occur for
longer read latencies" and recommented workaround is "Use SDMA (or
ADMA1) in case the AHB latency is larger than the “minimal time for
one block”. On top of that corresponding code in Linux
(https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mmc/host/sdhci-esdhc-imx.c?h=v4.15-rc3#n1061)
doesn't seem to use it as a 10-bit frequency field, treating it more
like a single-bit flag.

Thanks,
Andrey Smirnov



[Qemu-devel] [PATCH] hw/misc: Add code to emulate Xilinx Slave Serial port

2017-12-14 Thread Andrey Smirnov
Add code to emulate Xilinx Slave Serial FPGA configuration port.

Cc: "Edgar E. Iglesias" <edgar.igles...@gmail.com>
Cc: Alistair Francis <alistair.fran...@xilinx.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---

Integrating this into a build system via "obj-y" might not be the best
way. Does this code need a dedicated CONFIG_ symbol?

Thanks,
Andrey Smirnov


 hw/misc/Makefile.objs |   1 +
 hw/misc/xilinx_slave_serial.c | 105 ++
 include/hw/misc/xilinx_slave_serial.h |  21 +++
 3 files changed, 127 insertions(+)
 create mode 100644 hw/misc/xilinx_slave_serial.c
 create mode 100644 include/hw/misc/xilinx_slave_serial.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a68a201083..4599288e55 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -38,6 +38,7 @@ obj-$(CONFIG_IMX) += imx7_ccm.o
 obj-$(CONFIG_IMX) += imx2_wdt.o
 obj-$(CONFIG_IMX) += imx7_snvs.o
 obj-$(CONFIG_IMX) += imx7_gpr.o
+obj-y += xilinx_slave_serial.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/xilinx_slave_serial.c b/hw/misc/xilinx_slave_serial.c
new file mode 100644
index 00..607674fb60
--- /dev/null
+++ b/hw/misc/xilinx_slave_serial.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Code to emulate programming "port" of Xilinx FPGA in Slave Serial
+ * configuration connected via SPI, for more deatils see (p. 27):
+ *
+ * See https://www.xilinx.com/support/documentation/user_guides/ug380.pdf
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/xilinx_slave_serial.h"
+#include "qemu/log.h"
+
+enum {
+XILINX_SLAVE_SERIAL_STATE_RESET,
+XILINX_SLAVE_SERIAL_STATE_RECONFIGURATION,
+XILINX_SLAVE_SERIAL_STATE_DONE,
+};
+
+static void xilinx_slave_serial_update_outputs(XilinxSlaveSerialState *xlnxss)
+{
+qemu_set_irq(xlnxss->done,
+ xlnxss->state == XILINX_SLAVE_SERIAL_STATE_DONE);
+}
+
+static void xilinx_slave_serial_reset(DeviceState *dev)
+{
+XilinxSlaveSerialState *xlnxss = XILINX_SLAVE_SERIAL(dev);
+
+xlnxss->state = XILINX_SLAVE_SERIAL_STATE_RESET;
+
+xilinx_slave_serial_update_outputs(xlnxss);
+}
+
+static void xilinx_slave_serial_prog_b(void *opaque, int n, int level)
+{
+XilinxSlaveSerialState *xlnxss = XILINX_SLAVE_SERIAL(opaque);
+assert(n == 0);
+
+if (level) {
+xlnxss->state = XILINX_SLAVE_SERIAL_STATE_RECONFIGURATION;
+}
+
+xilinx_slave_serial_update_outputs(xlnxss);
+}
+
+static void xilinx_slave_serial_realize(SSISlave *ss, Error **errp)
+{
+DeviceState *dev = DEVICE(ss);
+XilinxSlaveSerialState *xlnxss = XILINX_SLAVE_SERIAL(ss);
+
+qdev_init_gpio_in_named(dev,
+xilinx_slave_serial_prog_b,
+XILINX_SLAVE_SERIAL_GPIO_PROG_B,
+1);
+qdev_init_gpio_out_named(dev, >done,
+ XILINX_SLAVE_SERIAL_GPIO_DONE, 1);
+}
+
+static uint32_t xilinx_slave_serial_transfer(SSISlave *ss, uint32_t tx)
+{
+XilinxSlaveSerialState *xlnxss = XILINX_SLAVE_SERIAL(ss);
+
+if (xlnxss->state == XILINX_SLAVE_SERIAL_STATE_RECONFIGURATION) {
+xlnxss->state = XILINX_SLAVE_SERIAL_STATE_DONE;
+}
+
+xilinx_slave_serial_update_outputs(xlnxss);
+return 0;
+}
+
+static void xilinx_slave_serial_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass   *dc = DEVICE_CLASS(klass);
+SSISlaveClass *k  = SSI_SLAVE_CLASS(klass);
+
+dc->reset  = xilinx_slave_serial_reset;
+dc->desc   = "Xilinx Slave Serial";
+k->realize = xilinx_slave_serial_realize;
+k->transfer= xilinx_slave_serial_transfer;
+/*
+ * Slave Serial configuration is not technically SPI and there's
+ * no CS signal
+ */
+k->set_cs  = NULL;
+k->cs_polarity = SSI_CS_NONE;
+}
+
+static const TypeInfo xilinx_slave_serial_info = {
+.name  = TYPE_XILINX_SLAVE_SERIAL,
+.parent= TYPE_SSI_SLAVE,
+.instance_size = sizeof(XilinxSlaveSerialState),
+.class_init= xilinx_slave_serial_class_init,
+};
+
+static void xilinx_slave_serial_register_type(void)
+{
+type_register_static(_slave_serial_info);
+}
+type_init(xilinx_slave_serial_register_type)
diff --git a/include/hw/misc/xilinx_slave_serial.h 
b/include/hw/misc/xilinx_slave_serial.h
new file mode 100644
index 00..f7b2e22be3
--- /dev/null
+++ b/include/hw/misc/xilinx_slave_serial.h
@@ -0,0 +1,21 @@
+#ifndef XILINX

[Qemu-devel] [PATCH] hw/misc: Add code to emulate PFUZE3000 PMIC

2017-12-14 Thread Andrey Smirnov
Add trivial code to emulate PFUZE3000 PMIC.

Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.orgn
Cc: yurov...@gmail.com
Cc: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---

Integrating this into a build system via "obj-y" might not be the best
way. Does this code need a dedicated CONFIG_ symbol?

Thanks,
Andrey Smirnov

 hw/misc/Makefile.objs   |   2 +
 hw/misc/pfuze3000.c | 212 
 include/hw/misc/pfuze3000.h |  48 ++
 3 files changed, 262 insertions(+)
 create mode 100644 hw/misc/pfuze3000.c
 create mode 100644 include/hw/misc/pfuze3000.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4599288e55..72dcd953bb 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -64,3 +64,5 @@ obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
 obj-y += mmio_interface.o
+
+obj-y += pfuze3000.o
diff --git a/hw/misc/pfuze3000.c b/hw/misc/pfuze3000.c
new file mode 100644
index 00..f414b7c0ba
--- /dev/null
+++ b/hw/misc/pfuze3000.c
@@ -0,0 +1,212 @@
+/*
+ *
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Author: Andrey Smirnov <andrew.smir...@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/i2c/i2c.h"
+#include "hw/misc/pfuze3000.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+
+#define PFUZE_NUMREGS   128
+#define PFUZE100_VOL_OFFSET 0
+#define PFUZE100_STANDBY_OFFSET 1
+#define PFUZE100_MODE_OFFSET3
+#define PFUZE100_CONF_OFFSET4
+
+#define PFUZE100_DEVICEID   0x0
+#define PFUZE100_REVID  0x3
+#define PFUZE100_FABID  0x4
+
+#define PFUZE100_COINVOL0x1a
+#define PFUZE100_SW1ABVOL   0x20
+#define PFUZE100_SW1ACONF   0x24
+#define PFUZE100_SW1CVOL0x2e
+#define PFUZE100_SW1BCONF   0x32
+#define PFUZE100_SW2VOL 0x35
+#define PFUZE100_SW3AVOL0x3c
+#define PFUZE100_SW3BVOL0x43
+#define PFUZE100_SW4VOL 0x4a
+#define PFUZE100_SWBSTCON1  0x66
+#define PFUZE100_VREFDDRCON 0x6a
+#define PFUZE100_VSNVSVOL   0x6b
+#define PFUZE100_VGEN1VOL   0x6c
+#define PFUZE100_VGEN2VOL   0x6d
+#define PFUZE100_VGEN3VOL   0x6e
+#define PFUZE100_VGEN4VOL   0x6f
+#define PFUZE100_VGEN5VOL   0x70
+#define PFUZE100_VGEN6VOL   0x71
+
+#define PFUZE100_INVAL  0xff
+
+static int pfuze3000_recv(I2CSlave *i2c)
+{
+PFuze3000State *s = PFUZE3000(i2c);
+
+const uint8_t reg = s->reg;
+
+s->reg = PFUZE100_INVAL;
+
+switch (reg) {
+case PFUZE100_DEVICEID:
+return 0x30;
+case PFUZE100_REVID:
+return 0x10;
+case PFUZE100_FABID:
+return 0x00;
+case PFUZE100_COINVOL:
+return s->coinvol;
+case PFUZE100_SW1ABVOL:
+return s->sw1abvol;
+case PFUZE100_SW1ACONF:
+return s->sw1aconf;
+case PFUZE100_SW1CVOL:
+return s->sw1cvol;
+case PFUZE100_SW1BCONF:
+return s->sw1bconf;
+case PFUZE100_SW2VOL:
+return s->sw2vol;
+case PFUZE100_SW3AVOL:
+return s->sw3avol;
+case PFUZE100_SW3BVOL:
+return s->sw3bvol;
+case PFUZE100_SW4VOL:
+return s->sw4vol;
+case PFUZE100_SWBSTCON1:
+return s->swbstcon1;
+case PFUZE100_VREFDDRCON:
+return s->vrefddrcon;
+case PFUZE100_VSNVSVOL:
+return s->vsnvsvol;
+case PFUZE100_VGEN1VOL:
+return s->vgen1vol;
+case PFUZE100_VGEN2VOL:
+return s->vgen2vol;
+case PFUZE100_VGEN3VOL:
+return s->vgen3vol;
+case PFUZE100_VGEN4VOL:
+return s->vgen4vol;
+case PFUZE100_VGEN5VOL:
+return s->vgen5vol;
+case PFUZE100_VGEN6VOL:
+return s->vgen6vol;
+}
+
+return -EINVAL;
+}
+
+static int pfuze3000_send(I2CSlave *i2c, uint8_t data)
+{
+PFuze3000State *s = PFUZE3000(i2c);
+
+switch (s->reg) {
+case PFUZE100_INVAL:
+s->reg = data;
+return 0;
+
+case PFUZE100_COINVOL:
+s->coinvol = data;
+break;
+case PFUZE100_SW1ABVOL:
+s->sw1abvol = data;
+break;
+case PFUZE100_SW1ACONF:
+s->sw1aconf = data;
+ 

[Qemu-devel] [PATCH v2 13/15] hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC

2017-12-14 Thread Andrey Smirnov
Convert i.MX6 to use TYPE_IMX_USDHC since that's what real HW comes
with.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/arm/fsl-imx6.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 2ed7146c52..b9249dbfc8 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -93,7 +93,7 @@ static void fsl_imx6_init(Object *obj)
 }
 
 for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
-object_initialize(>esdhc[i], sizeof(s->esdhc[i]), 
TYPE_SYSBUS_SDHCI);
+object_initialize(>esdhc[i], sizeof(s->esdhc[i]), TYPE_IMX_USDHC);
 qdev_set_parent_bus(DEVICE(>esdhc[i]), sysbus_get_default());
 snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
 object_property_add_child(obj, name, OBJECT(>esdhc[i]), NULL);
-- 
2.14.3




[Qemu-devel] [PATCH v2 15/15] sdhci: Implement write method of ACMD12ERRSTS register

2017-12-14 Thread Andrey Smirnov
Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/sd/sdhci.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 758af067f9..cb9e0db9fb 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1139,6 +1139,9 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, 
unsigned size)
 s->admasysaddr = (s->admasysaddr & (0xULL |
 ((uint64_t)mask << 32))) | ((uint64_t)value << 32);
 break;
+case SDHC_ACMD12ERRSTS:
+MASKED_WRITE(s->acmd12errsts, mask, value);
+break;
 case SDHC_FEAER:
 s->acmd12errsts |= value;
 s->errintsts |= (value >> 16) & s->errintstsen;
-- 
2.14.3




[Qemu-devel] [PATCH v2 07/15] imx_fec: Emulate SHIFT16 in ENETx_RACC

2017-12-14 Thread Andrey Smirnov
Needed to support latest Linux kernel driver which relies on that
functionality.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 23 +++
 include/hw/net/imx_fec.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 6feda18742..825c879a28 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1037,6 +1037,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
 uint8_t *crc_ptr;
 unsigned int buf_len;
 size_t size = len;
+bool shift16 = s->regs[ENET_RACC] & ENET_RACC_SHIFT16;
 
 FEC_PRINTF("len %d\n", (int)size);
 
@@ -1051,6 +1052,10 @@ static ssize_t imx_enet_receive(NetClientState *nc, 
const uint8_t *buf,
 crc = cpu_to_be32(crc32(~0, buf, size));
 crc_ptr = (uint8_t *) 
 
+if (shift16) {
+size += 2;
+}
+
 /* Huge frames are truncted.  */
 if (size > s->regs[ENET_FTRL]) {
 size = s->regs[ENET_FTRL];
@@ -1087,6 +1092,24 @@ static ssize_t imx_enet_receive(NetClientState *nc, 
const uint8_t *buf,
 buf_len += size - 4;
 }
 buf_addr = bd.data;
+
+if (shift16) {
+/*
+ * If SHIFT16 bit of ENETx_RACC register is set we need to
+ * align the payload to 4-byte boundary.
+ */
+const uint8_t zeros[2] = { 0 };
+
+dma_memory_write(_space_memory, buf_addr,
+ zeros, sizeof(zeros));
+
+buf_addr += sizeof(zeros);
+buf_len  -= sizeof(zeros);
+
+/* We only do this once per Ethernet frame */
+shift16 = false;
+}
+
 dma_memory_write(_space_memory, buf_addr, buf, buf_len);
 buf += buf_len;
 if (size < 4) {
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
index a390d704a6..af0840a0fa 100644
--- a/include/hw/net/imx_fec.h
+++ b/include/hw/net/imx_fec.h
@@ -170,6 +170,8 @@
 #define ENET_TWFR_TFWR_LENGTH  (6)
 #define ENET_TWFR_STRFWD   (1 << 8)
 
+#define ENET_RACC_SHIFT16  BIT(7)
+
 /* Buffer Descriptor.  */
 typedef struct {
 uint16_t length;
-- 
2.14.3




[Qemu-devel] [PATCH v2 08/15] imx_fec: Add support for multiple Tx DMA rings

2017-12-14 Thread Andrey Smirnov
More recent version of the IP block support more than one Tx DMA ring,
so add the code implementing that feature.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 133 ---
 include/hw/net/imx_fec.h |  18 ++-
 2 files changed, 130 insertions(+), 21 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 825c879a28..77d27f763e 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -196,6 +196,31 @@ static const char *imx_eth_reg_name(IMXFECState *s, 
uint32_t index)
 }
 }
 
+/*
+ * Versions of this device with more than one TX descriptor save the
+ * 2nd and 3rd descriptors in a subsection, to maintain migration
+ * compatibility with previous versions of the device that only
+ * supported a single descriptor.
+ */
+static bool imx_eth_is_multi_tx_ring(void *opaque)
+{
+IMXFECState *s = IMX_FEC(opaque);
+
+return s->tx_ring_num > 1;
+}
+
+static const VMStateDescription vmstate_imx_eth_txdescs = {
+.name = "imx.fec/txdescs",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = imx_eth_is_multi_tx_ring,
+.fields = (VMStateField[]) {
+ VMSTATE_UINT32(tx_descriptor[1], IMXFECState),
+ VMSTATE_UINT32(tx_descriptor[2], IMXFECState),
+ VMSTATE_END_OF_LIST()
+}
+};
+
 static const VMStateDescription vmstate_imx_eth = {
 .name = TYPE_IMX_FEC,
 .version_id = 2,
@@ -203,15 +228,18 @@ static const VMStateDescription vmstate_imx_eth = {
 .fields = (VMStateField[]) {
 VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
 VMSTATE_UINT32(rx_descriptor, IMXFECState),
-VMSTATE_UINT32(tx_descriptor, IMXFECState),
-
+VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
 VMSTATE_UINT32(phy_status, IMXFECState),
 VMSTATE_UINT32(phy_control, IMXFECState),
 VMSTATE_UINT32(phy_advertise, IMXFECState),
 VMSTATE_UINT32(phy_int, IMXFECState),
 VMSTATE_UINT32(phy_int_mask, IMXFECState),
 VMSTATE_END_OF_LIST()
-}
+},
+.subsections = (const VMStateDescription * []) {
+_imx_eth_txdescs,
+NULL
+},
 };
 
 #define PHY_INT_ENERGYON(1 << 7)
@@ -406,7 +434,7 @@ static void imx_fec_do_tx(IMXFECState *s)
 {
 int frame_size = 0, descnt = 0;
 uint8_t *ptr = s->frame;
-uint32_t addr = s->tx_descriptor;
+uint32_t addr = s->tx_descriptor[0];
 
 while (descnt++ < IMX_MAX_DESC) {
 IMXFECBufDesc bd;
@@ -447,16 +475,47 @@ static void imx_fec_do_tx(IMXFECState *s)
 }
 }
 
-s->tx_descriptor = addr;
+s->tx_descriptor[0] = addr;
 
 imx_eth_update(s);
 }
 
-static void imx_enet_do_tx(IMXFECState *s)
+static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
 {
 int frame_size = 0, descnt = 0;
+
 uint8_t *ptr = s->frame;
-uint32_t addr = s->tx_descriptor;
+uint32_t addr, int_txb, int_txf, tdsr;
+size_t ring;
+
+switch (index) {
+case ENET_TDAR:
+ring= 0;
+int_txb = ENET_INT_TXB;
+int_txf = ENET_INT_TXF;
+tdsr= ENET_TDSR;
+break;
+case ENET_TDAR1:
+ring= 1;
+int_txb = ENET_INT_TXB1;
+int_txf = ENET_INT_TXF1;
+tdsr= ENET_TDSR1;
+break;
+case ENET_TDAR2:
+ring= 2;
+int_txb = ENET_INT_TXB2;
+int_txf = ENET_INT_TXF2;
+tdsr= ENET_TDSR2;
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: bogus value for index %x\n",
+  __func__, index);
+abort();
+break;
+}
+
+addr = s->tx_descriptor[ring];
 
 while (descnt++ < IMX_MAX_DESC) {
 IMXENETBufDesc bd;
@@ -502,32 +561,32 @@ static void imx_enet_do_tx(IMXFECState *s)
 
 frame_size = 0;
 if (bd.option & ENET_BD_TX_INT) {
-s->regs[ENET_EIR] |= ENET_INT_TXF;
+s->regs[ENET_EIR] |= int_txf;
 }
 }
 if (bd.option & ENET_BD_TX_INT) {
-s->regs[ENET_EIR] |= ENET_INT_TXB;
+s->regs[ENET_EIR] |= int_txb;
 }
 bd.flags &= ~ENET_BD_R;
 /* Write back the modified descriptor.  */
 imx_enet_write_bd(, addr);
 /* Advance to the next descriptor.  */
 if ((bd.flags & ENET_BD_W) != 0) {
-addr = s->regs[ENET_TDSR];
+addr = s->regs[tdsr];
 } else {
 addr += sizeof(bd);
 }
 }
 
-s->tx_descriptor = addr;
+s->tx_descriptor[ring] = addr;

[Qemu-devel] [PATCH v2 14/15] sd: Check for READ_MULTIPLE_BLOCK size limit violation first

2017-12-14 Thread Andrey Smirnov
Check for READ_MULTIPLE_BLOCK size limit violation first as opposed to
doing at the end of the command handler. Consider the following
scenario:

Emulated host driver is trying to read last byte of the last sector
via CMD18/ADMA, so what would happen is the following:

1. "ret" is filled with desired byte and "sd->data_offset" is
   incremented to 512 by

ret = sd->data[sd->data_offset ++];

2. sd->data_offset >= io_len becomes true, so

sd->data_start += io_len;

   moves "sd->data_start" past valid data boundaries.

3. as a result "sd->data_start + io_len > sd->size" check becomes true
   and sd->card_status is marked with ADDRESS_ERROR, telling emulated
   host that the last CMD18 read failed, despite nothing bad/illegal
   happening.

To avoid having this false positive, move out-of-bounds check to
happen before BLK_READ_BLOCK(), so this way it will only trigger if
illegal read is truly about to happen.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/sd/sd.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index ba47bff4db..ce4ef17be3 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1797,8 +1797,17 @@ uint8_t sd_read_data(SDState *sd)
 break;
 
 case 18:   /* CMD18:  READ_MULTIPLE_BLOCK */
-if (sd->data_offset == 0)
+if (sd->data_offset == 0) {
+if (sd->data_start + io_len > sd->size) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Trying to read past card's capacity\n",
+  __func__);
+sd->card_status |= ADDRESS_ERROR;
+return 0x00;
+}
+
 BLK_READ_BLOCK(sd->data_start, io_len);
+}
 ret = sd->data[sd->data_offset ++];
 
 if (sd->data_offset >= io_len) {
@@ -1812,11 +1821,6 @@ uint8_t sd_read_data(SDState *sd)
 break;
 }
 }
-
-if (sd->data_start + io_len > sd->size) {
-sd->card_status |= ADDRESS_ERROR;
-break;
-}
 }
 break;
 
-- 
2.14.3




[Qemu-devel] [PATCH v2 06/15] imx_fec: Use MIN instead of explicit ternary operator

2017-12-14 Thread Andrey Smirnov
Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 50da91bf9e..6feda18742 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1076,7 +1076,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
   TYPE_IMX_FEC, __func__);
 break;
 }
-buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
+buf_len = MIN(size, s->regs[ENET_MRBR]);
 bd.length = buf_len;
 size -= buf_len;
 
-- 
2.14.3




[Qemu-devel] [PATCH v2 10/15] imx_fec: Fix a typo in imx_enet_receive()

2017-12-14 Thread Andrey Smirnov
Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 6cb9e2e20e..c1cf7f9c58 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1150,7 +1150,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
 size += 2;
 }
 
-/* Huge frames are truncted.  */
+/* Huge frames are truncated. */
 if (size > s->regs[ENET_FTRL]) {
 size = s->regs[ENET_FTRL];
 flags |= ENET_BD_TR | ENET_BD_LG;
-- 
2.14.3




[Qemu-devel] [PATCH v2 09/15] imx_fec: Use correct length for packet size

2017-12-14 Thread Andrey Smirnov
Use 'frame_size' instead of 'len' when calling qemu_send_packet(),
failing to do so results in malformed packets send in case when that
packed is fragmented into multiple DMA transactions.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 77d27f763e..6cb9e2e20e 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -556,7 +556,7 @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
 }
 /* Last buffer in frame.  */
 
-qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
+qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
 ptr = s->frame;
 
 frame_size = 0;
-- 
2.14.3




[Qemu-devel] [PATCH v2 03/15] imx_fec: Change queue flushing heuristics

2017-12-14 Thread Andrey Smirnov
In current implementation, packet queue flushing logic seem to suffer
from a deadlock like scenario if a packet is received by the interface
before before Rx ring is initialized by Guest's driver. Consider the
following sequence of events:

1. A QEMU instance is started against a TAP device on Linux
   host, running Linux guest, e. g., something to the effect
   of:

   qemu-system-arm \
  -net nic,model=imx.fec,netdev=lan0 \
  netdev tap,id=lan0,ifname=tap0,script=no,downscript=no \
  ... rest of the arguments ...

2. Once QEMU starts, but before guest reaches the point where
   FEC deriver is done initializing the HW, Guest, via TAP
   interface, receives a number of multicast MDNS packets from
   Host (not necessarily true for every OS, but it happens at
   least on Fedora 25)

3. Recieving a packet in such a state results in
   imx_eth_can_receive() returning '0', which in turn causes
   tap_send() to disable corresponding event (tap.c:203)

4. Once Guest's driver reaches the point where it is ready to
   recieve packets it prepares Rx ring descriptors and writes
   ENET_RDAR_RDAR to ENET_RDAR register to indicate to HW that
   more descriptors are ready. And at this points emulation
   layer does this:

 s->regs[index] = ENET_RDAR_RDAR;
 imx_eth_enable_rx(s);

   which, combined with:

  if (!s->regs[ENET_RDAR]) {
 qemu_flush_queued_packets(qemu_get_queue(s->nic));
  }

   results in Rx queue never being flushed and corresponding
   I/O event beign disabled.

To prevent the problem, change the code to always flush packet queue
when ENET_RDAR transitions 0 -> ENET_RDAR_RDAR.

Cc: Peter Maydell <peter.mayd...@linaro.org>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Philippe Mathieu-Daudé <f4...@amsat.org>
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---
 hw/net/imx_fec.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 8b2e4b8ffe..eb034ffd0c 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -533,7 +533,7 @@ static void imx_eth_do_tx(IMXFECState *s)
 }
 }
 
-static void imx_eth_enable_rx(IMXFECState *s)
+static void imx_eth_enable_rx(IMXFECState *s, bool flush)
 {
 IMXFECBufDesc bd;
 bool rx_ring_full;
@@ -544,7 +544,7 @@ static void imx_eth_enable_rx(IMXFECState *s)
 
 if (rx_ring_full) {
 FEC_PRINTF("RX buffer full\n");
-} else if (!s->regs[ENET_RDAR]) {
+} else if (flush) {
 qemu_flush_queued_packets(qemu_get_queue(s->nic));
 }
 
@@ -807,7 +807,7 @@ static void imx_eth_write(void *opaque, hwaddr offset, 
uint64_t value,
 if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
 if (!s->regs[index]) {
 s->regs[index] = ENET_RDAR_RDAR;
-imx_eth_enable_rx(s);
+imx_eth_enable_rx(s, true);
 }
 } else {
 s->regs[index] = 0;
@@ -930,7 +930,7 @@ static int imx_eth_can_receive(NetClientState *nc)
 
 FEC_PRINTF("\n");
 
-return s->regs[ENET_RDAR] ? 1 : 0;
+return !!s->regs[ENET_RDAR];
 }
 
 static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
@@ -1020,7 +1020,7 @@ static ssize_t imx_fec_receive(NetClientState *nc, const 
uint8_t *buf,
 }
 }
 s->rx_descriptor = addr;
-imx_eth_enable_rx(s);
+imx_eth_enable_rx(s, false);
 imx_eth_update(s);
 return len;
 }
@@ -1116,7 +1116,7 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
 }
 }
 s->rx_descriptor = addr;
-imx_eth_enable_rx(s);
+imx_eth_enable_rx(s, false);
 imx_eth_update(s);
 return len;
 }
-- 
2.14.3




  1   2   3   >