diff mbox

[v2,7/9] i.MX: Add i.MX6 SOC implementation.

Message ID 4499d69ec1326c07481e9d8178e64b63f9748706.1454967766.git.jcd@tribudubois.net (mailing list archive)
State New, archived
Headers show

Commit Message

Jean-Christophe DUBOIS Feb. 8, 2016, 10:08 p.m. UTC
For now we only support the following devices:
* up to 4 Cortex A9 cores
* A9 MPCORE (SCU, GIC, TWD)
* 5 i.MX UARTs
* 2 EPIT timers
* 1 GPT timer
* 3 I2C controllers
* 7 GPIO controllers
* 6 SDHC controllers
* 1 CCM device
* 1 SRC device
* various ROM/RAM areas.

Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
---

Changes since V1:
 * use g_strdup_printf/g_free instead of local char array.
 * output a message on exit for unsupported number of cores.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs            |   1 +
 hw/arm/fsl-imx6.c               | 407 ++++++++++++++++++++++++++++++++++++
 include/hw/arm/fsl-imx6.h       | 447 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 856 insertions(+)
 create mode 100644 hw/arm/fsl-imx6.c
 create mode 100644 include/hw/arm/fsl-imx6.h

Comments

Peter Maydell Feb. 16, 2016, 3:31 p.m. UTC | #1
On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> For now we only support the following devices:
> * up to 4 Cortex A9 cores
> * A9 MPCORE (SCU, GIC, TWD)
> * 5 i.MX UARTs
> * 2 EPIT timers
> * 1 GPT timer
> * 3 I2C controllers
> * 7 GPIO controllers
> * 6 SDHC controllers
> * 1 CCM device
> * 1 SRC device
> * various ROM/RAM areas.
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since V1:
>  * use g_strdup_printf/g_free instead of local char array.
>  * output a message on exit for unsupported number of cores.
>
>  default-configs/arm-softmmu.mak |   1 +
>  hw/arm/Makefile.objs            |   1 +
>  hw/arm/fsl-imx6.c               | 407 ++++++++++++++++++++++++++++++++++++
>  include/hw/arm/fsl-imx6.h       | 447 ++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 856 insertions(+)
>  create mode 100644 hw/arm/fsl-imx6.c
>  create mode 100644 include/hw/arm/fsl-imx6.h
>
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index d9b90a5..ba3a380 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -99,6 +99,7 @@ CONFIG_ALLWINNER_A10_PIT=y
>  CONFIG_ALLWINNER_A10_PIC=y
>  CONFIG_ALLWINNER_A10=y
>
> +CONFIG_FSL_IMX6=y
>  CONFIG_FSL_IMX31=y
>  CONFIG_FSL_IMX25=y
>
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 2195b60..ac383df 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -15,3 +15,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
>  obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
>  obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
>  obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
> +obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
> diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
> new file mode 100644
> index 0000000..0faae27
> --- /dev/null
> +++ b/hw/arm/fsl-imx6.c
> @@ -0,0 +1,407 @@
> +/*
> + * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
> + *
> + * i.MX6 SOC emulation.
> + *
> + * Based on hw/arm/fsl-imx31.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.
> + *
> + *  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 "hw/arm/fsl-imx6.h"

Include "osdep/qemu.h" first, please (see comments on patch 8).

> +#include "sysemu/sysemu.h"
> +#include "exec/address-spaces.h"
> +#include "hw/boards.h"
> +#include "sysemu/char.h"
> +#include "qemu/error-report.h"

> +static void fsl_imx6_realize(DeviceState *dev, Error **errp)
> +{
> +    FslIMX6State *s = FSL_IMX6(dev);
> +    uint16_t i;
> +    Error *err = NULL;
> +
> +    for (i = 0; i < smp_cpus; i++) {
> +
> +        if (smp_cpus == 1) {
> +            /* On uniprocessor, the CBAR is set to 0 */
> +            object_property_set_int(OBJECT(&s->cpu[i]), 0,
> +                                    "reset-cbar", &error_abort);

0 is the default for this property so you don't really need to set this.

> +        } else {
> +            object_property_set_int(OBJECT(&s->cpu[i]), FSL_IMX6_A9MPCORE_ADDR,
> +                                    "reset-cbar", &error_abort);
> +        }
> +
> +        /* All CPU but CPU 0 start in power off mode */
> +        if (i) {
> +            object_property_set_bool(OBJECT(&s->cpu[i]), true,
> +                                     "start-powered-off", &error_abort);
> +        }
> +
> +        object_property_set_bool(OBJECT(&s->cpu[i]), false,
> +                                 "has_el3", &error_abort);

Do the CPUs in this board really not have EL3 ?


Otherwise this looks OK.

thanks
-- PMM
Jean-Christophe DUBOIS Feb. 16, 2016, 8:49 p.m. UTC | #2
Le 16/02/2016 16:31, Peter Maydell a écrit :
> On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
>> For now we only support the following devices:
>> * up to 4 Cortex A9 cores
>> * A9 MPCORE (SCU, GIC, TWD)
>> * 5 i.MX UARTs
>> * 2 EPIT timers
>> * 1 GPT timer
>> * 3 I2C controllers
>> * 7 GPIO controllers
>> * 6 SDHC controllers
>> * 1 CCM device
>> * 1 SRC device
>> * various ROM/RAM areas.
>>
>> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
>> ---
>>
>> Changes since V1:
>>   * use g_strdup_printf/g_free instead of local char array.
>>   * output a message on exit for unsupported number of cores.
>>
>>   default-configs/arm-softmmu.mak |   1 +
>>   hw/arm/Makefile.objs            |   1 +
>>   hw/arm/fsl-imx6.c               | 407 ++++++++++++++++++++++++++++++++++++
>>   include/hw/arm/fsl-imx6.h       | 447 ++++++++++++++++++++++++++++++++++++++++
>>   4 files changed, 856 insertions(+)
>>   create mode 100644 hw/arm/fsl-imx6.c
>>   create mode 100644 include/hw/arm/fsl-imx6.h
>>
>> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
>> index d9b90a5..ba3a380 100644
>> --- a/default-configs/arm-softmmu.mak
>> +++ b/default-configs/arm-softmmu.mak
>> @@ -99,6 +99,7 @@ CONFIG_ALLWINNER_A10_PIT=y
>>   CONFIG_ALLWINNER_A10_PIC=y
>>   CONFIG_ALLWINNER_A10=y
>>
>> +CONFIG_FSL_IMX6=y
>>   CONFIG_FSL_IMX31=y
>>   CONFIG_FSL_IMX25=y
>>
>> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
>> index 2195b60..ac383df 100644
>> --- a/hw/arm/Makefile.objs
>> +++ b/hw/arm/Makefile.objs
>> @@ -15,3 +15,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
>>   obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
>>   obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
>>   obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
>> +obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
>> diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
>> new file mode 100644
>> index 0000000..0faae27
>> --- /dev/null
>> +++ b/hw/arm/fsl-imx6.c
>> @@ -0,0 +1,407 @@
>> +/*
>> + * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
>> + *
>> + * i.MX6 SOC emulation.
>> + *
>> + * Based on hw/arm/fsl-imx31.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.
>> + *
>> + *  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 "hw/arm/fsl-imx6.h"
> Include "osdep/qemu.h" first, please (see comments on patch 8).
>
>> +#include "sysemu/sysemu.h"
>> +#include "exec/address-spaces.h"
>> +#include "hw/boards.h"
>> +#include "sysemu/char.h"
>> +#include "qemu/error-report.h"
>> +static void fsl_imx6_realize(DeviceState *dev, Error **errp)
>> +{
>> +    FslIMX6State *s = FSL_IMX6(dev);
>> +    uint16_t i;
>> +    Error *err = NULL;
>> +
>> +    for (i = 0; i < smp_cpus; i++) {
>> +
>> +        if (smp_cpus == 1) {
>> +            /* On uniprocessor, the CBAR is set to 0 */
>> +            object_property_set_int(OBJECT(&s->cpu[i]), 0,
>> +                                    "reset-cbar", &error_abort);
> 0 is the default for this property so you don't really need to set this.
>
>> +        } else {
>> +            object_property_set_int(OBJECT(&s->cpu[i]), FSL_IMX6_A9MPCORE_ADDR,
>> +                                    "reset-cbar", &error_abort);
>> +        }
>> +
>> +        /* All CPU but CPU 0 start in power off mode */
>> +        if (i) {
>> +            object_property_set_bool(OBJECT(&s->cpu[i]), true,
>> +                                     "start-powered-off", &error_abort);
>> +        }
>> +
>> +        object_property_set_bool(OBJECT(&s->cpu[i]), false,
>> +                                 "has_el3", &error_abort);
> Do the CPUs in this board really not have EL3 ?

Well the Cortex A9 is certainly able to get to the secure mode. However, 
if I enable it (has_el3 set to true), the OS (Linux or Xvisor) will not 
boot. Disabling it allow both OS to boot on the emulated i.MX6.

Would you have some idea on the reason for this "hang" during the boot 
when EL3 is enabled?

JC

>
>
> Otherwise this looks OK.
>
> thanks
> -- PMM
>
Peter Maydell Feb. 16, 2016, 9:06 p.m. UTC | #3
On 16 February 2016 at 20:49, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> Le 16/02/2016 16:31, Peter Maydell a écrit :
>> On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net>
>> wrote:
>>> +        object_property_set_bool(OBJECT(&s->cpu[i]), false,
>>> +                                 "has_el3", &error_abort);
>>
>> Do the CPUs in this board really not have EL3 ?
>
>
> Well the Cortex A9 is certainly able to get to the secure mode. However, if
> I enable it (has_el3 set to true), the OS (Linux or Xvisor) will not boot.
> Disabling it allow both OS to boot on the emulated i.MX6.
>
> Would you have some idea on the reason for this "hang" during the boot when
> EL3 is enabled?

How are you booting the OS/hypervisor? Via -kernel or via -bios ?
Usually if it doesn't boot this is because there's some bit of
boot rom/loader code that runs on the real h/w and isn't being
run in your QEMU setup, that does the initial setup of the h/w
in secure mode. (In particular, if the secure side doesn't set
the GIC interrupts to be NS accessible then things don't work
very well.)

I wouldn't have expected that to be an issue for booting linux
via -kernel though because there we should be booting the kernel
NS and have a hack to configure the GIC appropriately.

Peter C may remember the details of how this should work
better than me.

thanks
-- PMM
Jean-Christophe DUBOIS Feb. 16, 2016, 9:47 p.m. UTC | #4
Le 16/02/2016 22:06, Peter Maydell a écrit :
> On 16 February 2016 at 20:49, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> Le 16/02/2016 16:31, Peter Maydell a écrit :
>>> On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net>
>>> wrote:
>>>> +        object_property_set_bool(OBJECT(&s->cpu[i]), false,
>>>> +                                 "has_el3", &error_abort);
>>> Do the CPUs in this board really not have EL3 ?
>>
>> Well the Cortex A9 is certainly able to get to the secure mode. However, if
>> I enable it (has_el3 set to true), the OS (Linux or Xvisor) will not boot.
>> Disabling it allow both OS to boot on the emulated i.MX6.
>>
>> Would you have some idea on the reason for this "hang" during the boot when
>> EL3 is enabled?
> How are you booting the OS/hypervisor? Via -kernel or via -bios ?

via -kernel ...

> Usually if it doesn't boot this is because there's some bit of
> boot rom/loader code that runs on the real h/w and isn't being
> run in your QEMU setup, that does the initial setup of the h/w
> in secure mode. (In particular, if the secure side doesn't set
> the GIC interrupts to be NS accessible then things don't work
> very well.)

Well I guess on real hw uboot is setting things so that everything work 
thereafter. But here I don't have uboot and I jump directly to Linux ...

In QEMU, other Cortex A9 (Versatilepb.c, Exynos, Zynq ...) are also 
setting has_el3 to false ...

JC
>
> I wouldn't have expected that to be an issue for booting linux
> via -kernel though because there we should be booting the kernel
> NS and have a hack to configure the GIC appropriately.
>
> Peter C may remember the details of how this should work
> better than me.
>
> thanks
> -- PMM
>
Peter Maydell Feb. 16, 2016, 9:57 p.m. UTC | #5
On 16 February 2016 at 21:47, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> In QEMU, other Cortex A9 (Versatilepb.c, Exynos, Zynq ...) are also setting
> has_el3 to false ...

So these generally are the "legacy" platforms which were
added before we ever had EL3 support in QEMU. For them it's hard
to turn the EL3 support on for the board even if in theory
it ought to be on, because we don't know what users are
running on it that we might break. With a new to QEMU board
we have an opportunity to get it right from the start.

-kernel I would expect to work, though, at least if the
only issue is the interrupt controller setup. It seems
worth investigating why it goes wrong.

thanks
-- PMM
Jean-Christophe DUBOIS Feb. 18, 2016, 8:51 p.m. UTC | #6
Le 16/02/2016 22:57, Peter Maydell a écrit :
> On 16 February 2016 at 21:47, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> In QEMU, other Cortex A9 (Versatilepb.c, Exynos, Zynq ...) are also setting
>> has_el3 to false ...
> So these generally are the "legacy" platforms which were
> added before we ever had EL3 support in QEMU. For them it's hard
> to turn the EL3 support on for the board even if in theory
> it ought to be on, because we don't know what users are
> running on it that we might break. With a new to QEMU board
> we have an opportunity to get it right from the start.

OK, so is the "highbank" the only Qemu Cortex A9 board supporting el3 yet?

>
> -kernel I would expect to work, though, at least if the
> only issue is the interrupt controller setup. It seems
> worth investigating why it goes wrong.

Well, I can boot uniprocessor (-smp 1) without trouble but if I turn 
logs on (guest_errors,unimp) I am getting a lot of

  * gic_dist_writeb: Bad offset 38x (a few at startup)
  * Ignoring attempt to switch CPSR_A flag from non-secure world with
    SCR.AW bit clear (a lot)
  * Ignoring attempt to switch CPSR_F flag from non-secure world with
    SCR.FW bit clear (a few)

I am not sure if this is a problem. Do you have some opinion on this?

When I turn SMP (-smp 2 or more), I am unable to complete the boot. As 
soon as my secondary cpu is started QEMU will continue to boot "very 
slowly" but doesn't get to the linux user prompt overnight.

JC

>
> thanks
> -- PMM
>
Peter Maydell Feb. 18, 2016, 9:46 p.m. UTC | #7
On 18 February 2016 at 20:51, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> Le 16/02/2016 22:57, Peter Maydell a écrit :
>
> On 16 February 2016 at 21:47, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>
> In QEMU, other Cortex A9 (Versatilepb.c, Exynos, Zynq ...) are also setting
> has_el3 to false ...
>
> So these generally are the "legacy" platforms which were
> added before we ever had EL3 support in QEMU. For them it's hard
> to turn the EL3 support on for the board even if in theory
> it ought to be on, because we don't know what users are
> running on it that we might break. With a new to QEMU board
> we have an opportunity to get it right from the start.
>
>
> OK, so is the "highbank" the only Qemu Cortex A9 board supporting
> el3 yet?

Yep. We don't have many A9 boards and most of those we do have
are in the 'legacy' bucket.

> -kernel I would expect to work, though, at least if the
> only issue is the interrupt controller setup. It seems
> worth investigating why it goes wrong.
>
>
> Well, I can boot uniprocessor (-smp 1) without trouble but if I turn logs on
> (guest_errors,unimp) I am getting a lot of
>
> gic_dist_writeb: Bad offset 38x (a few at startup)
> Ignoring attempt to switch CPSR_A flag from non-secure world with
> SCR.AW bit clear (a lot)
> Ignoring attempt to switch CPSR_F flag from non-secure world with
> SCR.FW bit clear (a few)

This would only be a problem if your kernel needed to use FIQ,
I think.

> I am not sure if this is a problem. Do you have some opinion on this?
>
> When I turn SMP (-smp 2 or more), I am unable to complete the boot. As soon
> as my secondary cpu is started QEMU will continue to boot "very slowly" but
> doesn't get to the linux user prompt overnight.

Does SMP work with EL3 not enabled, or is this a different bug?

thanks
-- PMM
Jean-Christophe DUBOIS Feb. 19, 2016, 6:32 a.m. UTC | #8
Le 18/02/2016 22:46, Peter Maydell a écrit :
> On 18 February 2016 at 20:51, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> Le 16/02/2016 22:57, Peter Maydell a écrit :
>>
>> On 16 February 2016 at 21:47, Jean-Christophe DUBOIS
>> <jcd@tribudubois.net> wrote:
>>
>> In QEMU, other Cortex A9 (Versatilepb.c, Exynos, Zynq ...) are also setting
>> has_el3 to false ...
>>
>> So these generally are the "legacy" platforms which were
>> added before we ever had EL3 support in QEMU. For them it's hard
>> to turn the EL3 support on for the board even if in theory
>> it ought to be on, because we don't know what users are
>> running on it that we might break. With a new to QEMU board
>> we have an opportunity to get it right from the start.
>>
>>
>> OK, so is the "highbank" the only Qemu Cortex A9 board supporting
>> el3 yet?
> Yep. We don't have many A9 boards and most of those we do have
> are in the 'legacy' bucket.
>
>> -kernel I would expect to work, though, at least if the
>> only issue is the interrupt controller setup. It seems
>> worth investigating why it goes wrong.
>>
>>
>> Well, I can boot uniprocessor (-smp 1) without trouble but if I turn logs on
>> (guest_errors,unimp) I am getting a lot of
>>
>> gic_dist_writeb: Bad offset 38x (a few at startup)
>> Ignoring attempt to switch CPSR_A flag from non-secure world with
>> SCR.AW bit clear (a lot)
>> Ignoring attempt to switch CPSR_F flag from non-secure world with
>> SCR.FW bit clear (a few)
> This would only be a problem if your kernel needed to use FIQ,
> I think.

It is a standard linux (4.5-rc1) so it should not use FIQ I guess.

Now why is the linux code trying to do things it is not allowed to do in 
its security level ?

Or would Linux expect the secure world to set these bits before running it?

>
>> I am not sure if this is a problem. Do you have some opinion on this?
>>
>> When I turn SMP (-smp 2 or more), I am unable to complete the boot. As soon
>> as my secondary cpu is started QEMU will continue to boot "very slowly" but
>> doesn't get to the linux user prompt overnight.
> Does SMP work with EL3 not enabled, or is this a different bug?

If I set has_el3 to false, I can boot the 4 cores without problem. With 
has_el3 set to true (default value) I am getting the above behavior 
(boot OK in uniprocessor mode, and misbehaving if -smp >= 2).

JC

>
> thanks
> -- PMM
>
Peter Maydell Feb. 19, 2016, 9:32 a.m. UTC | #9
On 19 February 2016 at 06:32, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> Le 18/02/2016 22:46, Peter Maydell a écrit :
>> Does SMP work with EL3 not enabled, or is this a different bug?
>
>
> If I set has_el3 to false, I can boot the 4 cores without problem. With
> has_el3 set to true (default value) I am getting the above behavior (boot OK
> in uniprocessor mode, and misbehaving if -smp >= 2).

Odd. If you can point me to a test image I can use to investigate
(preferably with System.map and commit hash of kernel used to build it)
I'll see if I can find time to have a look at what's going on there.

-- PMM
Jean-Christophe DUBOIS Feb. 19, 2016, 9:06 p.m. UTC | #10
Le 19/02/2016 10:32, Peter Maydell a écrit :
> On 19 February 2016 at 06:32, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> Le 18/02/2016 22:46, Peter Maydell a écrit :
>>> Does SMP work with EL3 not enabled, or is this a different bug?
>>
>> If I set has_el3 to false, I can boot the 4 cores without problem. With
>> has_el3 set to true (default value) I am getting the above behavior (boot OK
>> in uniprocessor mode, and misbehaving if -smp >= 2).
> Odd. If you can point me to a test image I can use to investigate
> (preferably with System.map and commit hash of kernel used to build it)
> I'll see if I can find time to have a look at what's going on there.

I put my test image at the following address:

http://dl.free.fr/rADch1Xnx

You will get a tgz file with the following files in it:

  * imx6q-sabrelite.dtb
  * README
  * rootfs.cpio.gz
  * System.map
  * zImage

Instruction to run the image are in the README file.

The kernel is compiled using the imx_v6_v7_defconfig file (without 
modification) in the linux source tree

Thanks

JC

>
> -- PMM
>
Jean-Christophe DUBOIS Feb. 20, 2016, 10:55 a.m. UTC | #11
Just to compare I tried to run Linux on QEMU emulating highbank.

For now I am unable to start in SMP mode. Only one core is activated.

And there is linux backtrace in L2C-310 init.

My command line:

# qemu-system-arm -smp 4 -M highbank -m 1024M -display none -no-reboot 
-kernel zImage -initrd rootfs.cpio.gz -dtb highbank.dtb -serial stdio

The kernel output:

    [    0.000000] Booting Linux on physical CPU 0x0
    [    0.000000] Linux version 4.5.0-rc1-00028-g03c21cb-dirty
    (jcd@jcd-U31SG) (gcc version 4.6.3 (GCC) ) #20 SMP Sat Feb 20
    11:27:10 CET 2016
    [    0.000000] CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7),
    cr=10c5387d
    [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT
    nonaliasing instruction cache
    [    0.000000] Machine model: Calxeda Highbank
    [    0.000000] cma: Reserved 64 MiB at 0x3c000000
    [    0.000000] Memory policy: Data cache writealloc
    [    0.000000] DT missing boot CPU MPIDR[23:0], fall back to default
    cpu_logical_map
    [    0.000000] psci: probing for conduit method from DT.
    [    0.000000] psci: Using PSCI v0.1 Function IDs from DT
    [    0.000000] PERCPU: Embedded 12 pages/cpu @ef7e3000 s18880 r8192
    d22080 u49152
    [    0.000000] Built 1 zonelists in Zone order, mobility grouping
    on.  Total pages: 260608
    [    0.000000] Kernel command line: console=ttyAMA0
    [    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)
    [    0.000000] Dentry cache hash table entries: 131072 (order: 7,
    524288 bytes)
    [    0.000000] Inode-cache hash table entries: 65536 (order: 6,
    262144 bytes)
    [    0.000000] Memory: 958304K/1048576K available (8557K kernel
    code, 1112K rwdata, 4036K rodata, 1104K init, 345K bss, 24736K
    reserved, 65536K cma-reserved, 196608K highmem)
    [    0.000000] Virtual kernel memory layout:
    [    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    [    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
    [    0.000000]     vmalloc : 0xf0800000 - 0xff800000   ( 240 MB)
    [    0.000000]     lowmem  : 0xc0000000 - 0xf0000000   ( 768 MB)
    [    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
    [    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
    [    0.000000]       .text : 0xc0208000 - 0xc0e554cc   (12598 kB)
    [    0.000000]       .init : 0xc0e56000 - 0xc0f6a000   (1104 kB)
    [    0.000000]       .data : 0xc0f6a000 - 0xc10803c0   (1113 kB)
    [    0.000000]        .bss : 0xc1083000 - 0xc10d9598   ( 346 kB)
    [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1,
    Nodes=1
    [    0.000000] Hierarchical RCU implementation.
    [    0.000000]     Build-time adjustment of leaf fanout to 32.
    [    0.000000]     RCU restricting CPUs from NR_CPUS=16 to nr_cpu_ids=1.
    [    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32,
    nr_cpu_ids=1
    [    0.000000] NR_IRQS:16 nr_irqs:16 16
    [    0.000000] L2C-310 erratum 769419 enabled
    [    0.000000] L2C-310 enabling early BRESP for Cortex-A9
    [    0.000000] ------------[ cut here ]------------
    [    0.000000] WARNING: CPU: 0 PID: 0 at
    arch/arm/mach-highbank/highbank.c:60
    highbank_l2c310_write_sec+0x34/0x58()
    [    0.000000] Highbank L2C310: ignoring write to reg 0x104
    [    0.000000] Modules linked in:
    [    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted
    4.5.0-rc1-00028-g03c21cb-dirty #20
    [    0.000000] Hardware name: Highbank
    [    0.000000] [<c02187b4>] (unwind_backtrace) from [<c0213e20>]
    (show_stack+0x10/0x14)
    [    0.000000] [<c0213e20>] (show_stack) from [<c048f9a4>]
    (dump_stack+0x70/0x8c)
    [    0.000000] [<c048f9a4>] (dump_stack) from [<c024ab30>]
    (warn_slowpath_common+0x74/0xac)
    [    0.000000] [<c024ab30>] (warn_slowpath_common) from [<c024abfc>]
    (warn_slowpath_fmt+0x30/0x40)
    [    0.000000] [<c024abfc>] (warn_slowpath_fmt) from [<c02292fc>]
    (highbank_l2c310_write_sec+0x34/0x58)
    [    0.000000] [<c02292fc>] (highbank_l2c310_write_sec) from
    [<c0223e44>] (l2c_configure+0x34/0x48)
    [    0.000000] [<c0223e44>] (l2c_configure) from [<c0224128>]
    (l2c310_configure+0xc/0x16c)
    [    0.000000] [<c0224128>] (l2c310_configure) from [<c0223f40>]
    (l2c_enable+0xe8/0xf8)
    [    0.000000] [<c0223f40>] (l2c_enable) from [<c0e5eb90>]
    (l2c310_enable+0x140/0x21c)
    [    0.000000] [<c0e5eb90>] (l2c310_enable) from [<c0e5f474>]
    (__l2c_init.part.6+0x19c/0x234)
    [    0.000000] [<c0e5f474>] (__l2c_init.part.6) from [<c0e5f7b4>]
    (l2x0_of_init+0x208/0x254)
    [    0.000000] [<c0e5f7b4>] (l2x0_of_init) from [<c0e5947c>]
    (init_IRQ+0x5c/0x80)
    [    0.000000] [<c0e5947c>] (init_IRQ) from [<c0e56adc>]
    (start_kernel+0x244/0x3dc)
    [    0.000000] [<c0e56adc>] (start_kernel) from [<0020807c>] (0x20807c)
    [    0.000000] ---[ end trace cb88537fdc8fa200 ]---
    [    0.000000] L2C-310 dynamic clock gating disabled, standby mode
    disabled
    [    0.000000] L2C-310 cache controller enabled, 8 ways, 128 kB
    [    0.000000] L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x02020000
    [    0.000000] clocksource: arm,sp804: mask: 0xffffffff max_cycles:
    0xffffffff, max_idle_ns: 12741736309 ns
    [    0.000184] sched_clock: 32 bits at 150MHz, resolution 6ns, wraps
    every 14316557820ns
    [    0.005851] Console: colour dummy device 80x30
    [    0.010978] Calibrating delay loop... 830.66 BogoMIPS (lpj=2076672)
    [    0.066316] pid_max: default: 32768 minimum: 301
    [    0.067955] Mount-cache hash table entries: 2048 (order: 1, 8192
    bytes)
    [    0.068026] Mountpoint-cache hash table entries: 2048 (order: 1,
    8192 bytes)
    [    0.080254] CPU: Testing write buffer coherency: ok
    [    0.091638] missing device node for CPU 0
    [    0.091966] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
    [    0.092492] Setting up static identity map for 0x209000 - 0x209098
    [    0.105477] Brought up 1 CPUs
    [    0.105595] SMP: Total of 1 processors activated (830.66 BogoMIPS).
    [    0.105723] CPU: All CPU(s) started in SVC mode.
    [    0.161221] devtmpfs: initialized
    [    0.173367] VFP support v0.3: implementor 41 architecture 3 part
    30 variant 9 rev 0
    [    0.191622] clocksource: jiffies: mask: 0xffffffff max_cycles:
    0xffffffff, max_idle_ns: 9556302231375000 ns
    [    0.218111] pinctrl core: initialized pinctrl subsystem
    [    0.240982] NET: Registered protocol family 16
    [    0.264314] DMA: preallocated 256 KiB pool for atomic coherent
    allocations
    [    0.273167] cpuidle: using governor menu
    [    0.291816] of_amba_device_create(): amba_device_add() failed
    (-19) for /soc/ipc@fff20000
    [    0.296693] of_amba_device_create(): amba_device_add() failed
    (-19) for /soc/dma@fff3d000
    [    0.301322] No ATAGs?
    [    0.301473] hw-breakpoint: debug architecture 0x4 unsupported.
    [    0.311969] Serial: AMBA PL011 UART driver
    [    0.314789] fff36000.serial: ttyAMA0 at MMIO 0xfff36000 (irq =
    30, base_baud = 0) is a PL011 rev1
    [    0.361986] console [ttyAMA0] enabled
    [    0.424008] vgaarb: loaded
    [    0.429273] SCSI subsystem initialized
    [    0.432446] usbcore: registered new interface driver usbfs
    [    0.433301] usbcore: registered new interface driver hub
    [    0.434118] usbcore: registered new device driver usb
    [    0.438497] pps_core: LinuxPPS API ver. 1 registered
    [    0.438988] pps_core: Software ver. 5.3.6 - Copyright 2005-2007
    Rodolfo Giometti <giometti@linux.it>
    [    0.439957] PTP clock support registered
    [    0.441054] EDAC MC: Ver: 3.0.0
    [    0.458770] clocksource: Switched to clocksource arm,sp804
    [    0.512003] NET: Registered protocol family 2
    [    0.519451] TCP established hash table entries: 8192 (order: 3,
    32768 bytes)
    [    0.520405] TCP bind hash table entries: 8192 (order: 4, 65536 bytes)
    [    0.522070] TCP: Hash tables configured (established 8192 bind 8192)
    [    0.523533] UDP hash table entries: 512 (order: 2, 16384 bytes)
    [    0.524236] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
    [    0.526354] NET: Registered protocol family 1
    [    0.531160] RPC: Registered named UNIX socket transport module.
    [    0.531952] RPC: Registered udp transport module.
    [    0.532391] RPC: Registered tcp transport module.
    [    0.532765] RPC: Registered tcp NFSv4.1 backchannel transport module.
    [    0.551747] Trying to unpack rootfs image as initramfs...
    [    0.772458] Freeing initrd memory: 428K (c8000000 - c806b000)
    [    0.774751] hw perfevents: enabled with armv7_cortex_a9 PMU
    driver, 1 counters available
    [    0.780779] futex hash table entries: 256 (order: 2, 16384 bytes)
    [    0.823585] squashfs: version 4.0 (2009/01/31) Phillip Lougher
    [    0.828308] NFS: Registering the id_resolver key type
    [    0.829517] Key type id_resolver registered
    [    0.829774] Key type id_legacy registered
    [    0.830580] ntfs: driver 2.1.32 [Flags: R/O].
    [    0.840916] bounce: pool size: 64 pages
    [    0.843410] Block layer SCSI generic (bsg) driver version 0.4
    loaded (major 249)
    [    0.844144] io scheduler noop registered
    [    0.844440] io scheduler deadline registered
    [    0.844923] io scheduler cfq registered (default)
    [    1.147672] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
    [    1.155398] SuperH (H)SCI(F) driver initialized
    [    1.158507] msm_serial: driver initialized
    [    1.159302] STMicroelectronics ASC driver initialized
    [    1.164268] [drm] Initialized drm 1.1.0 20060810
    [    1.232423] brd: module loaded
    [    1.272039] loop: module loaded
    [    1.281563] highbank-ahci ffe08000.sata: AHCI 0001.0000 32 slots
    1 ports 1.5 Gbps 0x1 impl platform mode
    [    1.282249] highbank-ahci ffe08000.sata: flags: ncq only
    [    1.290241] scsi host0: sata_highbank
    [    1.296846] ata1: SATA max UDMA/133 mmio [mem
    0xffe08000-0xffe17fff] port 0x100 irq 27
    [    1.317097] libphy: Fixed MDIO Bus: probed
    [    1.319831] CAN device driver interface
    [    1.322883] calxedaxgmac fff50000.ethernet (unnamed net_device)
    (uninitialized): h/w version is 0x1012
    [    1.327766] calxedaxgmac fff51000.ethernet (unnamed net_device)
    (uninitialized): h/w version is 0x1012
    [    1.333222] igb: Intel(R) Gigabit Ethernet Network Driver -
    version 5.3.0-k
    [    1.333607] igb: Copyright (c) 2007-2014 Intel Corporation.
    [    1.342007] pegasus: v0.9.3 (2013/04/25), Pegasus/Pegasus II USB
    Ethernet driver
    [    1.342613] usbcore: registered new interface driver pegasus
    [    1.343188] usbcore: registered new interface driver asix
    [    1.343679] usbcore: registered new interface driver ax88179_178a
    [    1.344164] usbcore: registered new interface driver cdc_ether
    [    1.344760] usbcore: registered new interface driver smsc75xx
    [    1.345337] usbcore: registered new interface driver smsc95xx
    [    1.346240] usbcore: registered new interface driver net1080
    [    1.346742] usbcore: registered new interface driver cdc_subset
    [    1.347219] usbcore: registered new interface driver zaurus
    [    1.347861] usbcore: registered new interface driver cdc_ncm
    [    1.352913] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI)
    Driver
    [    1.353397] ehci-pci: EHCI PCI platform driver
    [    1.354023] ehci-platform: EHCI generic platform driver
    [    1.354755] ehci-omap: OMAP-EHCI Host Controller driver
    [    1.355447] ehci-orion: EHCI orion driver
    [    1.356401] SPEAr-ehci: EHCI SPEAr driver
    [    1.357040] ehci-st: EHCI STMicroelectronics driver
    [    1.357691] ehci-exynos: EHCI EXYNOS driver
    [    1.358307] ehci-atmel: EHCI Atmel driver
    [    1.358907] tegra-ehci: Tegra EHCI driver
    [    1.359672] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
    [    1.360467] ohci-pci: OHCI PCI platform driver
    [    1.361146] ohci-platform: OHCI generic platform driver
    [    1.361889] ohci-omap3: OHCI OMAP3 driver
    [    1.362535] SPEAr-ohci: OHCI SPEAr driver
    [    1.363201] ohci-st: OHCI STMicroelectronics driver
    [    1.364030] ohci-atmel: OHCI Atmel driver
    [    1.366552] usbcore: registered new interface driver usb-storage
    [    1.376379] mousedev: PS/2 mouse device common for all mice
    [    1.389381] rtc-pl031 fff35000.rtc: rtc core: registered pl031 as
    rtc0
    [    1.396441] i2c /dev entries driver
    [    1.424256] hb_mc_edac fff00000.memory-controller: No ECC
    present, or ECC disabled
    [    1.429835] EDAC DEVICE0: Giving out device to module hb_l2_edac
    controller calxeda,hb-sregs-l2-ecc: DEV fff3c200.sregs (INTERRUPT)
    [    1.436472] sdhci: Secure Digital Host Controller Interface driver
    [    1.436868] sdhci: Copyright(c) Pierre Ossman
    [    1.442605] Synopsys Designware Multimedia Card Interface Driver
    [    1.446809] sdhci-pltfm: SDHCI platform and OF driver helper
    [    1.453659] ledtrig-cpu: registered to indicate activity on CPUs
    [    1.455151] usbcore: registered new interface driver usbhid
    [    1.455559] usbhid: USB HID core driver
    [    1.479532] NET: Registered protocol family 10
    [    1.489877] sit: IPv6 over IPv4 tunneling driver
    [    1.494441] NET: Registered protocol family 17
    [    1.494878] can: controller area network core (rev 20120528 abi 9)
    [    1.495609] NET: Registered protocol family 29
    [    1.495939] can: raw protocol (rev 20120528)
    [    1.496268] can: broadcast manager protocol (rev 20120528 t)
    [    1.496630] can: netlink gateway (rev 20130117) max_hops=1
    [    1.499025] Key type dns_resolver registered
    [    1.499704] ThumbEE CPU extension supported.
    [    1.500037] Registering SWP/SWPB emulation handler
    [    1.514185] rtc-pl031 fff35000.rtc: setting system clock to
    2016-02-20 10:36:54 UTC (1455964614)
    [    1.522492] uart-pl011 fff36000.serial: no DMA platform data
    [    1.769068] ata1: SATA link down (SStatus 0 SControl 300)
    [    1.801718] Freeing unused kernel memory: 1104K (c0e56000 - c0f6a000)
    Type exit when done.
    /bin/ash: can't access tty; job control turned off
    (:1) / #

And for sure there is only one CPU activated:

    (:1) / # cat /proc/interrupts
                CPU0
      16:       1003     GIC-0  29 Edge      twd
      17:          0     GIC-0  50 Level     timer
      25:          0     GIC-0 103 Level     fff3c200.sregs
      26:          0     GIC-0 104 Level     fff3c200.sregs
      27:          0     GIC-0 115 Level highbank-ahci[ffe08000.sata]
      29:          0     GIC-0  51 Level     rtc-pl031
      30:         30     GIC-0  52 Level     uart-pl011
      33:          8     GIC-0 109 Level     fff50000.ethernet
      34:          0     GIC-0 110 Level     fff50000.ethernet
      36:          0     GIC-0 112 Level     fff51000.ethernet
      37:          0     GIC-0 113 Level     fff51000.ethernet
    IPI0:          0  CPU wakeup interrupts
    IPI1:          0  Timer broadcast interrupts
    IPI2:          0  Rescheduling interrupts
    IPI3:          0  Function call interrupts
    IPI4:          0  CPU stop interrupts
    IPI5:          0  IRQ work interrupts
    IPI6:          0  completion interrupts
    Err:          0
    (:1) / #

Am I missing something?

JC

Le 19/02/2016 22:06, Jean-Christophe DUBOIS a écrit :
> Le 19/02/2016 10:32, Peter Maydell a écrit :
>> On 19 February 2016 at 06:32, Jean-Christophe DUBOIS
>> <jcd@tribudubois.net>  wrote:
>>> Le 18/02/2016 22:46, Peter Maydell a écrit :
>>>> Does SMP work with EL3 not enabled, or is this a different bug?
>>> If I set has_el3 to false, I can boot the 4 cores without problem. With
>>> has_el3 set to true (default value) I am getting the above behavior (boot OK
>>> in uniprocessor mode, and misbehaving if -smp >= 2).
>> Odd. If you can point me to a test image I can use to investigate
>> (preferably with System.map and commit hash of kernel used to build it)
>> I'll see if I can find time to have a look at what's going on there.
>
> I put my test image at the following address:
>
> http://dl.free.fr/rADch1Xnx
>
> You will get a tgz file with the following files in it:
>
>   * imx6q-sabrelite.dtb
>   * README
>   * rootfs.cpio.gz
>   * System.map
>   * zImage
>
> Instruction to run the image are in the README file.
>
> The kernel is compiled using the imx_v6_v7_defconfig file (without 
> modification) in the linux source tree
>
> Thanks
>
> JC
>
>> -- PMM
>>
>
Peter Crosthwaite Feb. 20, 2016, 3:30 p.m. UTC | #12
On Sat, Feb 20, 2016 at 2:55 AM, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> Just to compare I tried to run Linux on QEMU emulating highbank.
>
> For now I am unable to start in SMP mode. Only one core is activated.
>

This is probably due to the fact that the PSCI command encodings for
Highbank expected by the kernel are mismatched to the ones in QEMU. I
had some patches to change them, but once I got the PSCI right, the
boot hung (might be just extreme slowdown like you describe) and I
never got the time to fully debug it. SO there is a good chance
Highbank has the same bug.

Regards,
Peter
Jean-Christophe DUBOIS Feb. 20, 2016, 6:03 p.m. UTC | #13
Le 20/02/2016 16:30, Peter Crosthwaite a écrit :
> On Sat, Feb 20, 2016 at 2:55 AM, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> Just to compare I tried to run Linux on QEMU emulating highbank.
>>
>> For now I am unable to start in SMP mode. Only one core is activated.
>>
> This is probably due to the fact that the PSCI command encodings for
> Highbank expected by the kernel are mismatched to the ones in QEMU. I
> had some patches to change them, but once I got the PSCI right, the
> boot hung (might be just extreme slowdown like you describe) and I
> never got the time to fully debug it. SO there is a good chance
> Highbank has the same bug.

Thanks Peter,

So we are not sure we have a reference Cortex A9 platform working with 
has_el3 set to true.

This is annoying.

JC

>
> Regards,
> Peter
>
Peter Crosthwaite Feb. 21, 2016, 3:42 a.m. UTC | #14
On Sat, Feb 20, 2016 at 10:03 AM, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> Le 20/02/2016 16:30, Peter Crosthwaite a écrit :
>>
>> On Sat, Feb 20, 2016 at 2:55 AM, Jean-Christophe DUBOIS
>> <jcd@tribudubois.net> wrote:
>>>
>>> Just to compare I tried to run Linux on QEMU emulating highbank.
>>>
>>> For now I am unable to start in SMP mode. Only one core is activated.
>>>
>> This is probably due to the fact that the PSCI command encodings for
>> Highbank expected by the kernel are mismatched to the ones in QEMU. I
>> had some patches to change them, but once I got the PSCI right, the
>> boot hung (might be just extreme slowdown like you describe) and I
>> never got the time to fully debug it. SO there is a good chance
>> Highbank has the same bug.
>
>
> Thanks Peter,
>
> So we are not sure we have a reference Cortex A9 platform working with
> has_el3 set to true.
>

Not for SMP linux.

Regards,
Peter

> This is annoying.
>
> JC
>
>>
>> Regards,
>> Peter
>>
>
Jean-Christophe DUBOIS Feb. 21, 2016, 1:42 p.m. UTC | #15
Le 21/02/2016 04:42, Peter Crosthwaite a écrit :
> On Sat, Feb 20, 2016 at 10:03 AM, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> Le 20/02/2016 16:30, Peter Crosthwaite a écrit :
>>> On Sat, Feb 20, 2016 at 2:55 AM, Jean-Christophe DUBOIS
>>> <jcd@tribudubois.net> wrote:
>>>> Just to compare I tried to run Linux on QEMU emulating highbank.
>>>>
>>>> For now I am unable to start in SMP mode. Only one core is activated.
>>>>
>>> This is probably due to the fact that the PSCI command encodings for
>>> Highbank expected by the kernel are mismatched to the ones in QEMU. I
>>> had some patches to change them, but once I got the PSCI right, the
>>> boot hung (might be just extreme slowdown like you describe) and I
>>> never got the time to fully debug it. SO there is a good chance
>>> Highbank has the same bug.
>>
>> Thanks Peter,
>>
>> So we are not sure we have a reference Cortex A9 platform working with
>> has_el3 set to true.
>>
> Not for SMP linux.

And do we have other 32 bits Cortex (A5/A7/A15/...) that support has_el3 
in SMP?

JC

>
> Regards,
> Peter
>
>> This is annoying.
>>
>> JC
>>
>>> Regards,
>>> Peter
>>>
diff mbox

Patch

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d9b90a5..ba3a380 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -99,6 +99,7 @@  CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
 
+CONFIG_FSL_IMX6=y
 CONFIG_FSL_IMX31=y
 CONFIG_FSL_IMX25=y
 
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 2195b60..ac383df 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -15,3 +15,4 @@  obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
+obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
new file mode 100644
index 0000000..0faae27
--- /dev/null
+++ b/hw/arm/fsl-imx6.c
@@ -0,0 +1,407 @@ 
+/*
+ * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * i.MX6 SOC emulation.
+ *
+ * Based on hw/arm/fsl-imx31.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.
+ *
+ *  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 "hw/arm/fsl-imx6.h"
+#include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
+#include "hw/boards.h"
+#include "sysemu/char.h"
+#include "qemu/error-report.h"
+
+static void fsl_imx6_init(Object *obj)
+{
+    FslIMX6State *s = FSL_IMX6(obj);
+    int i;
+
+    if (smp_cpus > FSL_IMX6_NUM_CPUS) {
+        error_report("%s: Only %d CPUs are supported (%d requested)\n",
+                     TYPE_FSL_IMX6, FSL_IMX6_NUM_CPUS, smp_cpus);
+        exit(1);
+    }
+
+    for (i = 0; i < smp_cpus; i++) {
+        object_initialize(&s->cpu[i], sizeof(s->cpu[i]),
+                          "cortex-a9-" TYPE_ARM_CPU);
+    }
+
+    object_initialize(&s->a9mpcore, sizeof(s->a9mpcore), TYPE_A9MPCORE_PRIV);
+    qdev_set_parent_bus(DEVICE(&s->a9mpcore), sysbus_get_default());
+
+    object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX6_CCM);
+    qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
+
+    object_initialize(&s->src, sizeof(s->src), TYPE_IMX6_SRC);
+    qdev_set_parent_bus(DEVICE(&s->src), sysbus_get_default());
+
+    for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
+        object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
+        qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
+    }
+
+    object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX_GPT);
+    qdev_set_parent_bus(DEVICE(&s->gpt), sysbus_get_default());
+
+    for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) {
+        object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
+        qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
+    }
+
+    for (i = 0; i < FSL_IMX6_NUM_I2CS; i++) {
+        object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
+        qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
+    }
+
+    for (i = 0; i < FSL_IMX6_NUM_GPIOS; i++) {
+        object_initialize(&s->gpio[i], sizeof(s->gpio[i]), TYPE_IMX_GPIO);
+        qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus_get_default());
+    }
+
+    for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
+        object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_SYSBUS_SDHCI);
+        qdev_set_parent_bus(DEVICE(&s->esdhc[i]), sysbus_get_default());
+    }
+}
+
+static void fsl_imx6_realize(DeviceState *dev, Error **errp)
+{
+    FslIMX6State *s = FSL_IMX6(dev);
+    uint16_t i;
+    Error *err = NULL;
+
+    for (i = 0; i < smp_cpus; i++) {
+
+        if (smp_cpus == 1) {
+            /* On uniprocessor, the CBAR is set to 0 */
+            object_property_set_int(OBJECT(&s->cpu[i]), 0,
+                                    "reset-cbar", &error_abort);
+        } else {
+            object_property_set_int(OBJECT(&s->cpu[i]), FSL_IMX6_A9MPCORE_ADDR,
+                                    "reset-cbar", &error_abort);
+        }
+
+        /* All CPU but CPU 0 start in power off mode */
+        if (i) {
+            object_property_set_bool(OBJECT(&s->cpu[i]), true,
+                                     "start-powered-off", &error_abort);
+        }
+
+        object_property_set_bool(OBJECT(&s->cpu[i]), false,
+                                 "has_el3", &error_abort);
+
+        object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+    }
+
+    object_property_set_int(OBJECT(&s->a9mpcore), smp_cpus, "num-cpu",
+                            &error_abort);
+
+    object_property_set_int(OBJECT(&s->a9mpcore),
+                            FSL_IMX6_MAX_IRQ + GIC_INTERNAL, "num-irq",
+                            &error_abort);
+
+    object_property_set_bool(OBJECT(&s->a9mpcore), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->a9mpcore), 0, FSL_IMX6_A9MPCORE_ADDR);
+
+    for (i = 0; i < smp_cpus; i++) {
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i,
+                           qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i + smp_cpus,
+                           qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ));
+    }
+
+    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6_CCM_ADDR);
+
+    object_property_set_bool(OBJECT(&s->src), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6_SRC_ADDR);
+
+    /* Initialize all UARTs */
+    for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } serial_table[FSL_IMX6_NUM_UARTS] = {
+            { FSL_IMX6_UART1_ADDR, FSL_IMX6_UART1_IRQ },
+            { FSL_IMX6_UART2_ADDR, FSL_IMX6_UART2_IRQ },
+            { FSL_IMX6_UART3_ADDR, FSL_IMX6_UART3_IRQ },
+            { FSL_IMX6_UART4_ADDR, FSL_IMX6_UART4_IRQ },
+            { FSL_IMX6_UART5_ADDR, FSL_IMX6_UART5_IRQ },
+        };
+
+        if (i < MAX_SERIAL_PORTS) {
+            CharDriverState *chr;
+
+            chr = serial_hds[i];
+
+            if (!chr) {
+                char *label = g_strdup_printf("imx6.uart%d", i + 1);
+                chr = qemu_chr_new(label, "null", NULL);
+                g_free(label);
+                serial_hds[i] = chr;
+            }
+
+            qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
+        }
+
+        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
+                                            serial_table[i].irq));
+    }
+
+    s->gpt.ccm = IMX_CCM(&s->ccm);
+
+    object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX6_GPT_ADDR);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0,
+                       qdev_get_gpio_in(DEVICE(&s->a9mpcore),
+                                        FSL_IMX6_GPT_IRQ));
+
+    /* Initialize all EPIT timers */
+    for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } epit_table[FSL_IMX6_NUM_EPITS] = {
+            { FSL_IMX6_EPIT1_ADDR, FSL_IMX6_EPIT1_IRQ },
+            { FSL_IMX6_EPIT2_ADDR, FSL_IMX6_EPIT2_IRQ },
+        };
+
+        s->epit[i].ccm = IMX_CCM(&s->ccm);
+
+        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
+                                            epit_table[i].irq));
+    }
+
+    /* Initialize all I2C */
+    for (i = 0; i < FSL_IMX6_NUM_I2CS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } i2c_table[FSL_IMX6_NUM_I2CS] = {
+            { FSL_IMX6_I2C1_ADDR, FSL_IMX6_I2C1_IRQ },
+            { FSL_IMX6_I2C2_ADDR, FSL_IMX6_I2C2_IRQ },
+            { FSL_IMX6_I2C3_ADDR, FSL_IMX6_I2C3_IRQ }
+        };
+
+        /* Initialize the I2C */
+        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+        /* Map I2C memory */
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
+        /* Connect I2C IRQ to PIC */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
+                                            i2c_table[i].irq));
+    }
+
+    /* Initialize all GPIOs */
+    for (i = 0; i < FSL_IMX6_NUM_GPIOS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq_low;
+            unsigned int irq_high;
+        } gpio_table[FSL_IMX6_NUM_GPIOS] = {
+            {
+                FSL_IMX6_GPIO1_ADDR,
+                FSL_IMX6_GPIO1_LOW_IRQ,
+                FSL_IMX6_GPIO1_HIGH_IRQ
+            },
+            {
+                FSL_IMX6_GPIO2_ADDR,
+                FSL_IMX6_GPIO2_LOW_IRQ,
+                FSL_IMX6_GPIO2_HIGH_IRQ
+            },
+            {
+                FSL_IMX6_GPIO3_ADDR,
+                FSL_IMX6_GPIO3_LOW_IRQ,
+                FSL_IMX6_GPIO3_HIGH_IRQ
+            },
+            {
+                FSL_IMX6_GPIO4_ADDR,
+                FSL_IMX6_GPIO4_LOW_IRQ,
+                FSL_IMX6_GPIO4_HIGH_IRQ
+            },
+            {
+                FSL_IMX6_GPIO5_ADDR,
+                FSL_IMX6_GPIO5_LOW_IRQ,
+                FSL_IMX6_GPIO5_HIGH_IRQ
+            },
+            {
+                FSL_IMX6_GPIO6_ADDR,
+                FSL_IMX6_GPIO6_LOW_IRQ,
+                FSL_IMX6_GPIO6_HIGH_IRQ
+            },
+            {
+                FSL_IMX6_GPIO7_ADDR,
+                FSL_IMX6_GPIO7_LOW_IRQ,
+                FSL_IMX6_GPIO7_HIGH_IRQ
+            },
+        };
+
+        object_property_set_bool(OBJECT(&s->gpio[i]), true, "has-edge-sel",
+                                 &error_abort);
+        object_property_set_bool(OBJECT(&s->gpio[i]), true, "has-upper-pin-irq",
+                                 &error_abort);
+        object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
+        /* Connect GPIO IRQ to PIC */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
+                                            gpio_table[i].irq_low));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
+                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
+                                            gpio_table[i].irq_high));
+    }
+
+    /* Initialize all SDHC */
+    for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
+        static const struct {
+            hwaddr addr;
+            unsigned int irq;
+        } esdhc_table[FSL_IMX6_NUM_ESDHCS] = {
+            { FSL_IMX6_uSDHC1_ADDR, FSL_IMX6_uSDHC1_IRQ },
+            { FSL_IMX6_uSDHC2_ADDR, FSL_IMX6_uSDHC2_IRQ },
+            { FSL_IMX6_uSDHC3_ADDR, FSL_IMX6_uSDHC3_IRQ },
+            { FSL_IMX6_uSDHC4_ADDR, FSL_IMX6_uSDHC4_IRQ },
+        };
+
+        /* Initialize the I2C */
+        object_property_set_bool(OBJECT(&s->esdhc[i]), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+        /* Map SDHC memory */
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->esdhc[i]), 0, esdhc_table[i].addr);
+        /* Connect I2C IRQ to PIC */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->esdhc[i]), 0,
+                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
+                                            esdhc_table[i].irq));
+    }
+
+    /* ROM memory */
+    memory_region_init_rom_device(&s->rom, NULL, NULL, NULL, "imx6.rom",
+                                  FSL_IMX6_ROM_SIZE, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), FSL_IMX6_ROM_ADDR,
+                                &s->rom);
+
+    /* CAAM memory */
+    memory_region_init_rom_device(&s->caam, NULL, NULL, NULL, "imx6.caam",
+                                  FSL_IMX6_CAAM_MEM_SIZE, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), FSL_IMX6_CAAM_MEM_ADDR,
+                                &s->caam);
+
+    /* OCRAM memory */
+    memory_region_init_ram(&s->ocram, NULL, "imx6.ocram", FSL_IMX6_OCRAM_SIZE,
+                           &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ADDR,
+                                &s->ocram);
+    vmstate_register_ram_global(&s->ocram);
+
+    /* internal OCRAM (256 KB) is aliased over 1 MB */
+    memory_region_init_alias(&s->ocram_alias, NULL, "imx6.ocram_alias",
+                             &s->ocram, 0, FSL_IMX6_OCRAM_ALIAS_SIZE);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ALIAS_ADDR,
+                                &s->ocram_alias);
+}
+
+static void fsl_imx6_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = fsl_imx6_realize;
+
+    /*
+     * Reason: creates an ARM CPU, thus use after free(), see
+     * arm_cpu_class_init()
+     */
+    dc->cannot_destroy_with_object_finalize_yet = true;
+    dc->desc = "i.MX6 SOC";
+}
+
+static const TypeInfo fsl_imx6_type_info = {
+    .name = TYPE_FSL_IMX6,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(FslIMX6State),
+    .instance_init = fsl_imx6_init,
+    .class_init = fsl_imx6_class_init,
+};
+
+static void fsl_imx6_register_types(void)
+{
+    type_register_static(&fsl_imx6_type_info);
+}
+
+type_init(fsl_imx6_register_types)
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
new file mode 100644
index 0000000..301812d
--- /dev/null
+++ b/include/hw/arm/fsl-imx6.h
@@ -0,0 +1,447 @@ 
+/*
+ * Freescale i.MX31 SoC emulation
+ *
+ * Copyright (C) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * 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_IMX6_H
+#define FSL_IMX6_H
+
+#include "hw/arm/arm.h"
+#include "hw/cpu/a9mpcore.h"
+#include "hw/misc/imx6_ccm.h"
+#include "hw/misc/imx6_src.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 "exec/memory.h"
+
+#define TYPE_FSL_IMX6 "fsl,imx6"
+#define FSL_IMX6(obj) OBJECT_CHECK(FslIMX6State, (obj), TYPE_FSL_IMX6)
+
+#define FSL_IMX6_NUM_CPUS 4
+#define FSL_IMX6_NUM_UARTS 5
+#define FSL_IMX6_NUM_EPITS 2
+#define FSL_IMX6_NUM_I2CS 3
+#define FSL_IMX6_NUM_GPIOS 7
+#define FSL_IMX6_NUM_ESDHCS 4
+
+typedef struct FslIMX6State {
+    /*< private >*/
+    DeviceState parent_obj;
+
+    /*< public >*/
+    ARMCPU         cpu[FSL_IMX6_NUM_CPUS];
+    A9MPPrivState  a9mpcore;
+    IMX6CCMState   ccm;
+    IMX6SRCState   src;
+    IMXSerialState uart[FSL_IMX6_NUM_UARTS];
+    IMXGPTState    gpt;
+    IMXEPITState   epit[FSL_IMX6_NUM_EPITS];
+    IMXI2CState    i2c[FSL_IMX6_NUM_I2CS];
+    IMXGPIOState   gpio[FSL_IMX6_NUM_GPIOS];
+    SDHCIState     esdhc[FSL_IMX6_NUM_ESDHCS];
+    MemoryRegion   rom;
+    MemoryRegion   caam;
+    MemoryRegion   ocram;
+    MemoryRegion   ocram_alias;
+} FslIMX6State;
+
+
+#define FSL_IMX6_MMDC_ADDR 0x10000000
+#define FSL_IMX6_MMDC_SIZE 0xF0000000
+#define FSL_IMX6_EIM_MEM_ADDR 0x08000000
+#define FSL_IMX6_EIM_MEM_SIZE 0x8000000
+#define FSL_IMX6_IPU_2_ADDR 0x02800000
+#define FSL_IMX6_IPU_2_SIZE 0x400000
+#define FSL_IMX6_IPU_1_ADDR 0x02400000
+#define FSL_IMX6_IPU_1_SIZE 0x400000
+#define FSL_IMX6_MIPI_HSI_ADDR 0x02208000
+#define FSL_IMX6_MIPI_HSI_SIZE 0x4000
+#define FSL_IMX6_OPENVG_ADDR 0x02204000
+#define FSL_IMX6_OPENVG_SIZE 0x4000
+#define FSL_IMX6_SATA_ADDR 0x02200000
+#define FSL_IMX6_SATA_SIZE 0x4000
+#define FSL_IMX6_AIPS_2_ADDR 0x02100000
+#define FSL_IMX6_AIPS_2_SIZE 0x100000
+/* AIPS2 */
+#define FSL_IMX6_UART5_ADDR 0x021F4000
+#define FSL_IMX6_UART5_SIZE 0x4000
+#define FSL_IMX6_UART4_ADDR 0x021F0000
+#define FSL_IMX6_UART4_SIZE 0x4000
+#define FSL_IMX6_UART3_ADDR 0x021EC000
+#define FSL_IMX6_UART3_SIZE 0x4000
+#define FSL_IMX6_UART2_ADDR 0x021E8000
+#define FSL_IMX6_UART2_SIZE 0x4000
+#define FSL_IMX6_VDOA_ADDR 0x021E4000
+#define FSL_IMX6_VDOA_SIZE 0x4000
+#define FSL_IMX6_MIPI_DSI_ADDR 0x021E0000
+#define FSL_IMX6_MIPI_DSI_SIZE 0x4000
+#define FSL_IMX6_MIPI_CSI_ADDR 0x021DC000
+#define FSL_IMX6_MIPI_CSI_SIZE 0x4000
+#define FSL_IMX6_AUDMUX_ADDR 0x021D8000
+#define FSL_IMX6_AUDMUX_SIZE 0x4000
+#define FSL_IMX6_TZASC2_ADDR 0x021D4000
+#define FSL_IMX6_TZASC2_SIZE 0x4000
+#define FSL_IMX6_TZASC1_ADDR 0x021D0000
+#define FSL_IMX6_TZASC1_SIZE 0x4000
+#define FSL_IMX6_CSU_ADDR 0x021C0000
+#define FSL_IMX6_CSU_SIZE 0x4000
+#define FSL_IMX6_OCOTPCTRL_ADDR 0x021BC000
+#define FSL_IMX6_OCOTPCTRL_SIZE 0x4000
+#define FSL_IMX6_EIM_ADDR 0x021B8000
+#define FSL_IMX6_EIM_SIZE 0x4000
+#define FSL_IMX6_MMDC1_ADDR 0x021B4000
+#define FSL_IMX6_MMDC1_SIZE 0x4000
+#define FSL_IMX6_MMDC0_ADDR 0x021B0000
+#define FSL_IMX6_MMDC0_SIZE 0x4000
+#define FSL_IMX6_ROMCP_ADDR 0x021AC000
+#define FSL_IMX6_ROMCP_SIZE 0x4000
+#define FSL_IMX6_I2C3_ADDR 0x021A8000
+#define FSL_IMX6_I2C3_SIZE 0x4000
+#define FSL_IMX6_I2C2_ADDR 0x021A4000
+#define FSL_IMX6_I2C2_SIZE 0x4000
+#define FSL_IMX6_I2C1_ADDR 0x021A0000
+#define FSL_IMX6_I2C1_SIZE 0x4000
+#define FSL_IMX6_uSDHC4_ADDR 0x0219C000
+#define FSL_IMX6_uSDHC4_SIZE 0x4000
+#define FSL_IMX6_uSDHC3_ADDR 0x02198000
+#define FSL_IMX6_uSDHC3_SIZE 0x4000
+#define FSL_IMX6_uSDHC2_ADDR 0x02194000
+#define FSL_IMX6_uSDHC2_SIZE 0x4000
+#define FSL_IMX6_uSDHC1_ADDR 0x02190000
+#define FSL_IMX6_uSDHC1_SIZE 0x4000
+#define FSL_IMX6_MLB150_ADDR 0x0218C000
+#define FSL_IMX6_MLB150_SIZE 0x4000
+#define FSL_IMX6_ENET_ADDR 0x02188000
+#define FSL_IMX6_ENET_SIZE 0x4000
+#define FSL_IMX6_USBOH3_USB_ADDR 0x02184000
+#define FSL_IMX6_USBOH3_USB_SIZE 0x4000
+#define FSL_IMX6_AIPS2_CFG_ADDR 0x0217C000
+#define FSL_IMX6_AIPS2_CFG_SIZE 0x4000
+/* DAP */
+#define FSL_IMX6_PTF_CTRL_ADDR 0x02160000
+#define FSL_IMX6_PTF_CTRL_SIZE 0x1000
+#define FSL_IMX6_PTM3_ADDR 0x0215F000
+#define FSL_IMX6_PTM3_SIZE 0x1000
+#define FSL_IMX6_PTM2_ADDR 0x0215E000
+#define FSL_IMX6_PTM2_SIZE 0x1000
+#define FSL_IMX6_PTM1_ADDR 0x0215D000
+#define FSL_IMX6_PTM1_SIZE 0x1000
+#define FSL_IMX6_PTM0_ADDR 0x0215C000
+#define FSL_IMX6_PTM0_SIZE 0x1000
+#define FSL_IMX6_CTI3_ADDR 0x0215B000
+#define FSL_IMX6_CTI3_SIZE 0x1000
+#define FSL_IMX6_CTI2_ADDR 0x0215A000
+#define FSL_IMX6_CTI2_SIZE 0x1000
+#define FSL_IMX6_CTI1_ADDR 0x02159000
+#define FSL_IMX6_CTI1_SIZE 0x1000
+#define FSL_IMX6_CTI0_ADDR 0x02158000
+#define FSL_IMX6_CTI0_SIZE 0x1000
+#define FSL_IMX6_CPU3_PMU_ADDR 0x02157000
+#define FSL_IMX6_CPU3_PMU_SIZE 0x1000
+#define FSL_IMX6_CPU3_DEBUG_IF_ADDR 0x02156000
+#define FSL_IMX6_CPU3_DEBUG_IF_SIZE 0x1000
+#define FSL_IMX6_CPU2_PMU_ADDR 0x02155000
+#define FSL_IMX6_CPU2_PMU_SIZE 0x1000
+#define FSL_IMX6_CPU2_DEBUG_IF_ADDR 0x02154000
+#define FSL_IMX6_CPU2_DEBUG_IF_SIZE 0x1000
+#define FSL_IMX6_CPU1_PMU_ADDR 0x02153000
+#define FSL_IMX6_CPU1_PMU_SIZE 0x1000
+#define FSL_IMX6_CPU1_DEBUG_IF_ADDR 0x02152000
+#define FSL_IMX6_CPU1_DEBUG_IF_SIZE 0x1000
+#define FSL_IMX6_CPU0_PMU_ADDR 0x02151000
+#define FSL_IMX6_CPU0_PMU_SIZE 0x1000
+#define FSL_IMX6_CPU0_DEBUG_IF_ADDR 0x02150000
+#define FSL_IMX6_CPU0_DEBUG_IF_SIZE 0x1000
+#define FSL_IMX6_CA9_INTEG_ADDR 0x0214F000
+#define FSL_IMX6_CA9_INTEG_SIZE 0x1000
+#define FSL_IMX6_FUNNEL_ADDR 0x02144000
+#define FSL_IMX6_FUNNEL_SIZE 0x1000
+#define FSL_IMX6_TPIU_ADDR 0x02143000
+#define FSL_IMX6_TPIU_SIZE 0x1000
+#define FSL_IMX6_EXT_CTI_ADDR 0x02142000
+#define FSL_IMX6_EXT_CTI_SIZE 0x1000
+#define FSL_IMX6_ETB_ADDR 0x02141000
+#define FSL_IMX6_ETB_SIZE 0x1000
+#define FSL_IMX6_DAP_ROM_TABLE_ADDR 0x02140000
+#define FSL_IMX6_DAP_ROM_TABLE_SIZE 0x1000
+/* DAP end */
+#define FSL_IMX6_CAAM_ADDR 0x02100000
+#define FSL_IMX6_CAAM_SIZE 0x10000
+/* AIPS2 end */
+#define FSL_IMX6_AIPS_1_ADDR 0x02000000
+#define FSL_IMX6_AIPS_1_SIZE 0x100000
+/* AIPS1 */
+#define FSL_IMX6_SDMA_ADDR 0x020EC000
+#define FSL_IMX6_SDMA_SIZE 0x4000
+#define FSL_IMX6_DCIC2_ADDR 0x020E8000
+#define FSL_IMX6_DCIC2_SIZE 0x4000
+#define FSL_IMX6_DCIC1_ADDR 0x020E4000
+#define FSL_IMX6_DCIC1_SIZE 0x4000
+#define FSL_IMX6_IOMUXC_ADDR 0x020E0000
+#define FSL_IMX6_IOMUXC_SIZE 0x4000
+#define FSL_IMX6_PGCARM_ADDR 0x020DCA00
+#define FSL_IMX6_PGCARM_SIZE 0x20
+#define FSL_IMX6_PGCPU_ADDR 0x020DC260
+#define FSL_IMX6_PGCPU_SIZE 0x20
+#define FSL_IMX6_GPC_ADDR 0x020DC000
+#define FSL_IMX6_GPC_SIZE 0x4000
+#define FSL_IMX6_SRC_ADDR 0x020D8000
+#define FSL_IMX6_SRC_SIZE 0x4000
+#define FSL_IMX6_EPIT2_ADDR 0x020D4000
+#define FSL_IMX6_EPIT2_SIZE 0x4000
+#define FSL_IMX6_EPIT1_ADDR 0x020D0000
+#define FSL_IMX6_EPIT1_SIZE 0x4000
+#define FSL_IMX6_SNVSHP_ADDR 0x020CC000
+#define FSL_IMX6_SNVSHP_SIZE 0x4000
+#define FSL_IMX6_USBPHY2_ADDR 0x020CA000
+#define FSL_IMX6_USBPHY2_SIZE 0x1000
+#define FSL_IMX6_USBPHY1_ADDR 0x020C9000
+#define FSL_IMX6_USBPHY1_SIZE 0x1000
+#define FSL_IMX6_ANALOG_ADDR 0x020C8000
+#define FSL_IMX6_ANALOG_SIZE 0x1000
+#define FSL_IMX6_CCM_ADDR 0x020C4000
+#define FSL_IMX6_CCM_SIZE 0x4000
+#define FSL_IMX6_WDOG2_ADDR 0x020C0000
+#define FSL_IMX6_WDOG2_SIZE 0x4000
+#define FSL_IMX6_WDOG1_ADDR 0x020BC000
+#define FSL_IMX6_WDOG1_SIZE 0x4000
+#define FSL_IMX6_KPP_ADDR 0x020B8000
+#define FSL_IMX6_KPP_SIZE 0x4000
+#define FSL_IMX6_GPIO7_ADDR 0x020B4000
+#define FSL_IMX6_GPIO7_SIZE 0x4000
+#define FSL_IMX6_GPIO6_ADDR 0x020B0000
+#define FSL_IMX6_GPIO6_SIZE 0x4000
+#define FSL_IMX6_GPIO5_ADDR 0x020AC000
+#define FSL_IMX6_GPIO5_SIZE 0x4000
+#define FSL_IMX6_GPIO4_ADDR 0x020A8000
+#define FSL_IMX6_GPIO4_SIZE 0x4000
+#define FSL_IMX6_GPIO3_ADDR 0x020A4000
+#define FSL_IMX6_GPIO3_SIZE 0x4000
+#define FSL_IMX6_GPIO2_ADDR 0x020A0000
+#define FSL_IMX6_GPIO2_SIZE 0x4000
+#define FSL_IMX6_GPIO1_ADDR 0x0209C000
+#define FSL_IMX6_GPIO1_SIZE 0x4000
+#define FSL_IMX6_GPT_ADDR 0x02098000
+#define FSL_IMX6_GPT_SIZE 0x4000
+#define FSL_IMX6_CAN2_ADDR 0x02094000
+#define FSL_IMX6_CAN2_SIZE 0x4000
+#define FSL_IMX6_CAN1_ADDR 0x02090000
+#define FSL_IMX6_CAN1_SIZE 0x4000
+#define FSL_IMX6_PWM4_ADDR 0x0208C000
+#define FSL_IMX6_PWM4_SIZE 0x4000
+#define FSL_IMX6_PWM3_ADDR 0x02088000
+#define FSL_IMX6_PWM3_SIZE 0x4000
+#define FSL_IMX6_PWM2_ADDR 0x02084000
+#define FSL_IMX6_PWM2_SIZE 0x4000
+#define FSL_IMX6_PWM1_ADDR 0x02080000
+#define FSL_IMX6_PWM1_SIZE 0x4000
+#define FSL_IMX6_AIPS1_CFG_ADDR 0x0207C000
+#define FSL_IMX6_AIPS1_CFG_SIZE 0x4000
+#define FSL_IMX6_VPU_ADDR 0x02040000
+#define FSL_IMX6_VPU_SIZE 0x3C000
+#define FSL_IMX6_AIPS1_SPBA_ADDR 0x0203C000
+#define FSL_IMX6_AIPS1_SPBA_SIZE 0x4000
+#define FSL_IMX6_ASRC_ADDR 0x02034000
+#define FSL_IMX6_ASRC_SIZE 0x4000
+#define FSL_IMX6_SSI3_ADDR 0x02030000
+#define FSL_IMX6_SSI3_SIZE 0x4000
+#define FSL_IMX6_SSI2_ADDR 0x0202C000
+#define FSL_IMX6_SSI2_SIZE 0x4000
+#define FSL_IMX6_SSI1_ADDR 0x02028000
+#define FSL_IMX6_SSI1_SIZE 0x4000
+#define FSL_IMX6_ESAI_ADDR 0x02024000
+#define FSL_IMX6_ESAI_SIZE 0x4000
+#define FSL_IMX6_UART1_ADDR 0x02020000
+#define FSL_IMX6_UART1_SIZE 0x4000
+#define FSL_IMX6_eCSPI5_ADDR 0x02018000
+#define FSL_IMX6_eCSPI5_SIZE 0x4000
+#define FSL_IMX6_eCSPI4_ADDR 0x02014000
+#define FSL_IMX6_eCSPI4_SIZE 0x4000
+#define FSL_IMX6_eCSPI3_ADDR 0x02010000
+#define FSL_IMX6_eCSPI3_SIZE 0x4000
+#define FSL_IMX6_eCSPI2_ADDR 0x0200C000
+#define FSL_IMX6_eCSPI2_SIZE 0x4000
+#define FSL_IMX6_eCSPI1_ADDR 0x02008000
+#define FSL_IMX6_eCSPI1_SIZE 0x4000
+#define FSL_IMX6_SPDIF_ADDR 0x02004000
+#define FSL_IMX6_SPDIF_SIZE 0x4000
+/* AIPS1 end */
+#define FSL_IMX6_PCIe_REG_ADDR 0x01FFC000
+#define FSL_IMX6_PCIe_REG_SIZE 0x4000
+#define FSL_IMX6_PCIe_ADDR 0x01000000
+#define FSL_IMX6_PCIe_SIZE 0xFFC000
+#define FSL_IMX6_GPV_1_PL301_CFG_ADDR 0x00C00000
+#define FSL_IMX6_GPV_1_PL301_CFG_SIZE 0x100000
+#define FSL_IMX6_GPV_0_PL301_CFG_ADDR 0x00B00000
+#define FSL_IMX6_GPV_0_PL301_CFG_SIZE 0x100000
+#define FSL_IMX6_PL310_ADDR 0x00A02000
+#define FSL_IMX6_PL310_SIZE 0x1000
+#define FSL_IMX6_A9MPCORE_ADDR 0x00A00000
+#define FSL_IMX6_A9MPCORE_SIZE 0x2000
+#define FSL_IMX6_OCRAM_ALIAS_ADDR 0x00940000
+#define FSL_IMX6_OCRAM_ALIAS_SIZE 0xC0000
+#define FSL_IMX6_OCRAM_ADDR 0x00900000
+#define FSL_IMX6_OCRAM_SIZE 0x40000
+#define FSL_IMX6_GPV_4_PL301_CFG_ADDR 0x00800000
+#define FSL_IMX6_GPV_4_PL301_CFG_SIZE 0x100000
+#define FSL_IMX6_GPV_3_PL301_CFG_ADDR 0x00300000
+#define FSL_IMX6_GPV_3_PL301_CFG_SIZE 0x100000
+#define FSL_IMX6_GPV_2_PL301_CFG_ADDR 0x00200000
+#define FSL_IMX6_GPV_2_PL301_CFG_SIZE 0x100000
+#define FSL_IMX6_DTCP_ADDR 0x00138000
+#define FSL_IMX6_DTCP_SIZE 0x4000
+#define FSL_IMX6_GPU_2D_ADDR 0x00134000
+#define FSL_IMX6_GPU_2D_SIZE 0x4000
+#define FSL_IMX6_GPU_3D_ADDR 0x00130000
+#define FSL_IMX6_GPU_3D_SIZE 0x4000
+#define FSL_IMX6_HDMI_ADDR 0x00120000
+#define FSL_IMX6_HDMI_SIZE 0x9000
+#define FSL_IMX6_BCH_ADDR 0x00114000
+#define FSL_IMX6_BCH_SIZE 0x4000
+#define FSL_IMX6_GPMI_ADDR 0x00112000
+#define FSL_IMX6_GPMI_SIZE 0x2000
+#define FSL_IMX6_APBH_BRIDGE_DMA_ADDR 0x00110000
+#define FSL_IMX6_APBH_BRIDGE_DMA_SIZE 0x2000
+#define FSL_IMX6_CAAM_MEM_ADDR 0x00100000
+#define FSL_IMX6_CAAM_MEM_SIZE 0x4000
+#define FSL_IMX6_ROM_ADDR 0x00000000
+#define FSL_IMX6_ROM_SIZE 0x18000
+
+#define FSL_IMX6_IOMUXC_IRQ 0
+#define FSL_IMX6_DAP_IRQ 1
+#define FSL_IMX6_SDMA_IRQ 2
+#define FSL_IMX6_VPU_JPEG_IRQ 3
+#define FSL_IMX6_SNVS_PMIC_IRQ 4
+#define FSL_IMX6_IPU1_ERROR_IRQ 5
+#define FSL_IMX6_IPU1_SYNC_IRQ 6
+#define FSL_IMX6_IPU2_ERROR_IRQ 7
+#define FSL_IMX6_IPU2_SYNC_IRQ 8
+#define FSL_IMX6_GPU3D_IRQ 9
+#define FSL_IMX6_R2D_IRQ 10
+#define FSL_IMX6_V2D_IRQ 11
+#define FSL_IMX6_VPU_IRQ 12
+#define FSL_IMX6_APBH_BRIDGE_DMA_IRQ 13
+#define FSL_IMX6_EIM_IRQ 14
+#define FSL_IMX6_BCH_IRQ 15
+#define FSL_IMX6_GPMI_IRQ 16
+#define FSL_IMX6_DTCP_IRQ 17
+#define FSL_IMX6_VDOA_IRQ 18
+#define FSL_IMX6_SNVS_CONS_IRQ 19
+#define FSL_IMX6_SNVS_SEC_IRQ 20
+#define FSL_IMX6_CSU_IRQ 21
+#define FSL_IMX6_uSDHC1_IRQ 22
+#define FSL_IMX6_uSDHC2_IRQ 23
+#define FSL_IMX6_uSDHC3_IRQ 24
+#define FSL_IMX6_uSDHC4_IRQ 25
+#define FSL_IMX6_UART1_IRQ 26
+#define FSL_IMX6_UART2_IRQ 27
+#define FSL_IMX6_UART3_IRQ 28
+#define FSL_IMX6_UART4_IRQ 29
+#define FSL_IMX6_UART5_IRQ 30
+#define FSL_IMX6_ECSPI1_IRQ 31
+#define FSL_IMX6_ECSPI2_IRQ 32
+#define FSL_IMX6_ECSPI3_IRQ 33
+#define FSL_IMX6_ECSPI4_IRQ 34
+#define FSL_IMX6_ECSPI5_IRQ 35
+#define FSL_IMX6_I2C1_IRQ 36
+#define FSL_IMX6_I2C2_IRQ 37
+#define FSL_IMX6_I2C3_IRQ 38
+#define FSL_IMX6_SATA_IRQ 39
+#define FSL_IMX6_USB_HOST1_IRQ 40
+#define FSL_IMX6_USB_HOST2_IRQ 41
+#define FSL_IMX6_USB_HOST3_IRQ 42
+#define FSL_IMX6_USB_OTG_IRQ 43
+#define FSL_IMX6_USB_PHY_UTMI0_IRQ 44
+#define FSL_IMX6_USB_PHY_UTMI1_IRQ 45
+#define FSL_IMX6_SSI1_IRQ 46
+#define FSL_IMX6_SSI2_IRQ 47
+#define FSL_IMX6_SSI3_IRQ 48
+#define FSL_IMX6_TEMP_IRQ 49
+#define FSL_IMX6_ASRC_IRQ 50
+#define FSL_IMX6_ESAI_IRQ 51
+#define FSL_IMX6_SPDIF_IRQ 52
+#define FSL_IMX6_MLB150_IRQ 53
+#define FSL_IMX6_PMU1_IRQ 54
+#define FSL_IMX6_GPT_IRQ 55
+#define FSL_IMX6_EPIT1_IRQ 56
+#define FSL_IMX6_EPIT2_IRQ 57
+#define FSL_IMX6_GPIO1_INT7_IRQ 58
+#define FSL_IMX6_GPIO1_INT6_IRQ 59
+#define FSL_IMX6_GPIO1_INT5_IRQ 60
+#define FSL_IMX6_GPIO1_INT4_IRQ 61
+#define FSL_IMX6_GPIO1_INT3_IRQ 62
+#define FSL_IMX6_GPIO1_INT2_IRQ 63
+#define FSL_IMX6_GPIO1_INT1_IRQ 64
+#define FSL_IMX6_GPIO1_INT0_IRQ 65
+#define FSL_IMX6_GPIO1_LOW_IRQ 66
+#define FSL_IMX6_GPIO1_HIGH_IRQ 67
+#define FSL_IMX6_GPIO2_LOW_IRQ 68
+#define FSL_IMX6_GPIO2_HIGH_IRQ 69
+#define FSL_IMX6_GPIO3_LOW_IRQ 70
+#define FSL_IMX6_GPIO3_HIGH_IRQ 71
+#define FSL_IMX6_GPIO4_LOW_IRQ 72
+#define FSL_IMX6_GPIO4_HIGH_IRQ 73
+#define FSL_IMX6_GPIO5_LOW_IRQ 74
+#define FSL_IMX6_GPIO5_HIGH_IRQ 75
+#define FSL_IMX6_GPIO6_LOW_IRQ 76
+#define FSL_IMX6_GPIO6_HIGH_IRQ 77
+#define FSL_IMX6_GPIO7_LOW_IRQ 78
+#define FSL_IMX6_GPIO7_HIGH_IRQ 79
+#define FSL_IMX6_WDOG1_IRQ 80
+#define FSL_IMX6_WDOG2_IRQ 81
+#define FSL_IMX6_KPP_IRQ 82
+#define FSL_IMX6_PWM1_IRQ 83
+#define FSL_IMX6_PWM2_IRQ 84
+#define FSL_IMX6_PWM3_IRQ 85
+#define FSL_IMX6_PWM4_IRQ 86
+#define FSL_IMX6_CCM1_IRQ 87
+#define FSL_IMX6_CCM2_IRQ 88
+#define FSL_IMX6_GPC_IRQ 89
+#define FSL_IMX6_SRC_IRQ 91
+#define FSL_IMX6_CPU_L2_IRQ 92
+#define FSL_IMX6_CPU_PARITY_IRQ 93
+#define FSL_IMX6_CPU_PERF_IRQ 94
+#define FSL_IMX6_CPU_CTI_IRQ 95
+#define FSL_IMX6_SRC_COMB_IRQ 96
+#define FSL_IMX6_MIPI_CSI1_IRQ 100
+#define FSL_IMX6_MIPI_CSI2_IRQ 101
+#define FSL_IMX6_MIPI_DSI_IRQ 102
+#define FSL_IMX6_MIPI_HSI_IRQ 103
+#define FSL_IMX6_SJC_IRQ 104
+#define FSL_IMX6_CAAM0_IRQ 105
+#define FSL_IMX6_CAAM1_IRQ 106
+#define FSL_IMX6_ASC1_IRQ 108
+#define FSL_IMX6_ASC2_IRQ 109
+#define FSL_IMX6_FLEXCAN1_IRQ 110
+#define FSL_IMX6_FLEXCAN2_IRQ 111
+#define FSL_IMX6_HDMI_MASTER_IRQ 115
+#define FSL_IMX6_HDMI_CEC_IRQ 116
+#define FSL_IMX6_MLB150_LOW_IRQ 117
+#define FSL_IMX6_ENET_MAC_IRQ 118
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
+#define FSL_IMX6_PCIE1_IRQ 120
+#define FSL_IMX6_PCIE2_IRQ 121
+#define FSL_IMX6_PCIE3_IRQ 122
+#define FSL_IMX6_PCIE4_IRQ 123
+#define FSL_IMX6_DCIC1_IRQ 124
+#define FSL_IMX6_DCIC2_IRQ 125
+#define FSL_IMX6_MLB150_HIGH_IRQ 126
+#define FSL_IMX6_PMU2_IRQ 127
+#define FSL_IMX6_MAX_IRQ 128
+
+#endif /* FSL_IMX6_H */