qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support
@ 2016-02-08 22:08 Jean-Christophe Dubois
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 1/9] i.MX: Allow GPT timer to rollover Jean-Christophe Dubois
                   ` (9 more replies)
  0 siblings, 10 replies; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

This patch series adds support for the Freescale i.MX6 processor.

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
* 7 GPIO controllers
* 6 SDHC controllers
* 1 CCM device
* 1 SRC device
* 3 I2C devices
* various ROM/RAM areas.

This also adds the sabrelite board as a an actual platform for i.MX6.

This series was tested by booting a 4.4 linux kernel (using the
imx_v6_v7_defconfig file as kernel configuration).

Note1: as sabrelite uses uart2 as console, you have to redirect the second
QEMU serial port to stdout.
    qemu-system-arm -M sabrelite -display none ... -serial null -serial stdio

Note2: as the SPI controller is not yet supported in QEMU for i.MX you need
to disable SPI controllers in Linux DTS tree. Otherwise Linux would hang
during the boot waiting for a SPI device to respond.

Note3: You need to disable the GPIO section related to physical push buttons
in the Linux DTS tree in order to avoid excecive interrupt triggering on 
GPIO devices for non existant buttons.

Jean-Christophe Dubois (9):
  i.MX: Allow GPT timer to rollover.
  i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency.
  i.MX: Remove CCM useless clock computation handling.
  i.MX: Add the CLK_IPG_HIGH clock
  i.MX: Add i.MX6 CCM and ANALOG device.
  i.MX: Add i.MX6 System Reset Controller device.
  i.MX: Add i.MX6 SOC implementation.
  i.MX: Add sabrelite i.MX6 emulation.
  i.MX: Add missing descriptions in devices.

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs            |   1 +
 hw/arm/fsl-imx25.c              |   1 +
 hw/arm/fsl-imx31.c              |   1 +
 hw/arm/fsl-imx6.c               | 407 +++++++++++++++++++++
 hw/arm/sabrelite.c              |  93 +++++
 hw/i2c/imx_i2c.c                |   1 +
 hw/misc/Makefile.objs           |   2 +
 hw/misc/imx25_ccm.c             |  29 +-
 hw/misc/imx31_ccm.c             |  35 +-
 hw/misc/imx6_ccm.c              | 773 ++++++++++++++++++++++++++++++++++++++++
 hw/misc/imx6_src.c              | 353 ++++++++++++++++++
 hw/net/imx_fec.c                |   1 +
 hw/timer/imx_epit.c             |   8 +-
 hw/timer/imx_gpt.c              |  43 +--
 include/hw/arm/fsl-imx6.h       | 447 +++++++++++++++++++++++
 include/hw/misc/imx6_ccm.h      | 197 ++++++++++
 include/hw/misc/imx6_src.h      |  73 ++++
 include/hw/misc/imx_ccm.h       |  10 +-
 19 files changed, 2384 insertions(+), 92 deletions(-)
 create mode 100644 hw/arm/fsl-imx6.c
 create mode 100644 hw/arm/sabrelite.c
 create mode 100644 hw/misc/imx6_ccm.c
 create mode 100644 hw/misc/imx6_src.c
 create mode 100644 include/hw/arm/fsl-imx6.h
 create mode 100644 include/hw/misc/imx6_ccm.h
 create mode 100644 include/hw/misc/imx6_src.h

-- 
2.5.0

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 1/9] i.MX: Allow GPT timer to rollover.
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:19   ` Peter Maydell
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 2/9] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency Jean-Christophe Dubois
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

GPT timer need to rollover when it reaches 0xffffffff.

It also need to reset to 0 when in "restart mode" and crossing the
compare 1 register.

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

Changes since V1:
 * None

 hw/timer/imx_gpt.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index b1893b8..b227256 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -133,7 +133,7 @@ static inline uint32_t imx_gpt_find_limit(uint32_t count, uint32_t reg,
 static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
 {
     uint32_t timeout = GPT_TIMER_MAX;
-    uint32_t count = 0;
+    uint32_t count;
     long long limit;
 
     if (!(s->cr & GPT_CR_EN)) {
@@ -141,20 +141,23 @@ static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
         return;
     }
 
-    if (event) {
-        /* This is a timer event  */
+    /* update the count */
+    count = imx_gpt_update_count(s);
 
-        if ((s->cr & GPT_CR_FRR)  && (s->next_timeout != GPT_TIMER_MAX)) {
-            /*
-             * if we are in free running mode and we have not reached
-             * the GPT_TIMER_MAX limit, then update the count
+    if (event) {
+        /*
+         * This is an event (the ptimer reached 0 and stopped), and the
+         * timer counter is now equal to s->next_timeout.
+         */
+        if (!(s->cr & GPT_CR_FRR) && (count == s->ocr1)) {
+            /* We are in restart mode and we crossed the compare channel 1
+             * value. We need to reset the counter to 0.
              */
-            count = imx_gpt_update_count(s);
+            count = s->cnt = s->next_timeout = 0;
+        } else if (count == GPT_TIMER_MAX) {
+            /* We reached GPT_TIMER_MAX so we need to rollover */
+            count = s->cnt = s->next_timeout = 0;
         }
-    } else {
-        /* not a timer event, then just update the count */
-
-        count = imx_gpt_update_count(s);
     }
 
     /* now, find the next timeout related to count */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 2/9] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency.
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 1/9] i.MX: Allow GPT timer to rollover Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:20   ` Peter Maydell
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 3/9] i.MX: Remove CCM useless clock computation handling Jean-Christophe Dubois
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

This way all CCM clock defines/enums are named CLK_XXX

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

Changes since V1:
 * Not present on V1

 hw/misc/imx25_ccm.c       |  2 +-
 hw/misc/imx31_ccm.c       |  2 +-
 hw/timer/imx_epit.c       |  2 +-
 hw/timer/imx_gpt.c        | 10 +++++-----
 include/hw/misc/imx_ccm.h |  2 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index 23759ca..cc0e893 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -181,7 +181,7 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
     DPRINTF("Clock = %d)\n", clock);
 
     switch (clock) {
-    case NOCLK:
+    case CLK_NONE:
         break;
     case CLK_MPLL:
         freq = imx25_ccm_get_mpll_clk(dev);
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 47d6ead..10c78f3 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -208,7 +208,7 @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
     uint32_t freq = 0;
 
     switch (clock) {
-    case NOCLK:
+    case CLK_NONE:
         break;
     case CLK_MCU:
         freq = imx31_ccm_get_mcu_clk(dev);
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 50bf83c..f7772cc 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -51,7 +51,7 @@ static char const *imx_epit_reg_name(uint32_t reg)
  * These are typical.
  */
 static const IMXClk imx_epit_clocks[] =  {
-    NOCLK,    /* 00 disabled */
+    CLK_NONE, /* 00 disabled */
     CLK_IPG,  /* 01 ipg_clk, ~532MHz */
     CLK_IPG,  /* 10 ipg_clk_highfreq */
     CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index b227256..d1c0294 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -80,14 +80,14 @@ static const VMStateDescription vmstate_imx_timer_gpt = {
 };
 
 static const IMXClk imx_gpt_clocks[] = {
-    NOCLK,    /* 000 No clock source */
+    CLK_NONE, /* 000 No clock source */
     CLK_IPG,  /* 001 ipg_clk, 532MHz*/
     CLK_IPG,  /* 010 ipg_clk_highfreq */
-    NOCLK,    /* 011 not defined */
+    CLK_NONE, /* 011 not defined */
     CLK_32k,  /* 100 ipg_clk_32k */
-    NOCLK,    /* 101 not defined */
-    NOCLK,    /* 110 not defined */
-    NOCLK,    /* 111 not defined */
+    CLK_NONE, /* 101 not defined */
+    CLK_NONE, /* 110 not defined */
+    CLK_NONE, /* 111 not defined */
 };
 
 static void imx_gpt_set_freq(IMXGPTState *s)
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 5c4b795..74e2705 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -43,7 +43,7 @@ typedef struct IMXCCMState {
 } IMXCCMState;
 
 typedef enum  {
-    NOCLK,
+    CLK_NONE,
     CLK_MPLL,
     CLK_UPLL,
     CLK_MCU,
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 3/9] i.MX: Remove CCM useless clock computation handling.
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 1/9] i.MX: Allow GPT timer to rollover Jean-Christophe Dubois
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 2/9] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:20   ` Peter Maydell
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 4/9] i.MX: Add the CLK_IPG_HIGH clock Jean-Christophe Dubois
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

Most clocks supported by the CCM are useless to the qemu framework.

Only clocks related to timers (EPIT, GPT, PWM, WATCHDOG, ...) are usefull
to QEMU code.

Therefore this patch removes clock computation handling for all clocks but:
* CLK_NONE,
* CLK_IPG,
* CLK_32k

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

Changes since V1:
 * move NOCLK renaming in its own patch
 * move CLK_IPG_HIGH addition in its own patch

 hw/misc/imx25_ccm.c       | 26 --------------------------
 hw/misc/imx31_ccm.c       | 32 --------------------------------
 include/hw/misc/imx_ccm.h |  7 -------
 3 files changed, 65 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index cc0e893..e74486f 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -119,20 +119,6 @@ static uint32_t imx25_ccm_get_mpll_clk(IMXCCMState *dev)
     return freq;
 }
 
-static uint32_t imx25_ccm_get_upll_clk(IMXCCMState *dev)
-{
-    uint32_t freq = 0;
-    IMX25CCMState *s = IMX25_CCM(dev);
-
-    if (!EXTRACT(s->reg[IMX25_CCM_CCTL_REG], UPLL_DIS)) {
-        freq = imx_ccm_calc_pll(s->reg[IMX25_CCM_UPCTL_REG], CKIH_FREQ);
-    }
-
-    DPRINTF("freq = %d\n", freq);
-
-    return freq;
-}
-
 static uint32_t imx25_ccm_get_mcu_clk(IMXCCMState *dev)
 {
     uint32_t freq;
@@ -183,18 +169,6 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
     switch (clock) {
     case CLK_NONE:
         break;
-    case CLK_MPLL:
-        freq = imx25_ccm_get_mpll_clk(dev);
-        break;
-    case CLK_UPLL:
-        freq = imx25_ccm_get_upll_clk(dev);
-        break;
-    case CLK_MCU:
-        freq = imx25_ccm_get_mcu_clk(dev);
-        break;
-    case CLK_AHB:
-        freq = imx25_ccm_get_ahb_clk(dev);
-        break;
     case CLK_IPG:
         freq = imx25_ccm_get_ipg_clk(dev);
         break;
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 10c78f3..dee0b11 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -151,32 +151,6 @@ static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
     return freq;
 }
 
-static uint32_t imx31_ccm_get_mcu_clk(IMXCCMState *dev)
-{
-    uint32_t freq;
-    IMX31CCMState *s = IMX31_CCM(dev);
-
-    freq = imx31_ccm_get_mcu_main_clk(dev)
-           / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MCU));
-
-    DPRINTF("freq = %d\n", freq);
-
-    return freq;
-}
-
-static uint32_t imx31_ccm_get_hsp_clk(IMXCCMState *dev)
-{
-    uint32_t freq;
-    IMX31CCMState *s = IMX31_CCM(dev);
-
-    freq = imx31_ccm_get_mcu_main_clk(dev)
-           / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], HSP));
-
-    DPRINTF("freq = %d\n", freq);
-
-    return freq;
-}
-
 static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
 {
     uint32_t freq;
@@ -210,12 +184,6 @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
     switch (clock) {
     case CLK_NONE:
         break;
-    case CLK_MCU:
-        freq = imx31_ccm_get_mcu_clk(dev);
-        break;
-    case CLK_HSP:
-        freq = imx31_ccm_get_hsp_clk(dev);
-        break;
     case CLK_IPG:
         freq = imx31_ccm_get_ipg_clk(dev);
         break;
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 74e2705..378b78d 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -44,14 +44,7 @@ typedef struct IMXCCMState {
 
 typedef enum  {
     CLK_NONE,
-    CLK_MPLL,
-    CLK_UPLL,
-    CLK_MCU,
-    CLK_HSP,
-    CLK_MAX,
-    CLK_AHB,
     CLK_IPG,
-    CLK_PER,
     CLK_32k
 } IMXClk;
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 4/9] i.MX: Add the CLK_IPG_HIGH clock
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
                   ` (2 preceding siblings ...)
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 3/9] i.MX: Remove CCM useless clock computation handling Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:20   ` Peter Maydell
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device Jean-Christophe Dubois
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

EPIT, GPT and other i.MX timers are using "abstract" clocks among which
a CLK_IPG_HIGH clock.

On i.MX25 and i.MX31 CLK_IPG and CLK_IPG_HIGH are mapped to the same clock
but on other SOC like i.MX6 they are mapped to distinct clocks.

This patch add the CLK_IPG_HIGH to prepare for SOC where these 2 clocks are
different.

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

Changes since V1:
 * Not present on V1 

 hw/misc/imx25_ccm.c       |  1 +
 hw/misc/imx31_ccm.c       |  1 +
 hw/timer/imx_epit.c       |  8 ++++----
 hw/timer/imx_gpt.c        | 16 ++++++++--------
 include/hw/misc/imx_ccm.h |  1 +
 5 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index e74486f..caceb0e 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -170,6 +170,7 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
     case CLK_NONE:
         break;
     case CLK_IPG:
+    case CLK_IPG_HIGH:
         freq = imx25_ccm_get_ipg_clk(dev);
         break;
     case CLK_32k:
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index dee0b11..96ba2cb 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -185,6 +185,7 @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
     case CLK_NONE:
         break;
     case CLK_IPG:
+    case CLK_IPG_HIGH:
         freq = imx31_ccm_get_ipg_clk(dev);
         break;
     case CLK_32k:
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index f7772cc..ecd2e5a 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -51,10 +51,10 @@ static char const *imx_epit_reg_name(uint32_t reg)
  * These are typical.
  */
 static const IMXClk imx_epit_clocks[] =  {
-    CLK_NONE, /* 00 disabled */
-    CLK_IPG,  /* 01 ipg_clk, ~532MHz */
-    CLK_IPG,  /* 10 ipg_clk_highfreq */
-    CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
+    CLK_NONE,      /* 00 disabled */
+    CLK_IPG,       /* 01 ipg_clk, ~532MHz */
+    CLK_IPG_HIGH,  /* 10 ipg_clk_highfreq */
+    CLK_32k,       /* 11 ipg_clk_32k -- ~32kHz */
 };
 
 /*
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index d1c0294..e69456d 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -80,14 +80,14 @@ static const VMStateDescription vmstate_imx_timer_gpt = {
 };
 
 static const IMXClk imx_gpt_clocks[] = {
-    CLK_NONE, /* 000 No clock source */
-    CLK_IPG,  /* 001 ipg_clk, 532MHz*/
-    CLK_IPG,  /* 010 ipg_clk_highfreq */
-    CLK_NONE, /* 011 not defined */
-    CLK_32k,  /* 100 ipg_clk_32k */
-    CLK_NONE, /* 101 not defined */
-    CLK_NONE, /* 110 not defined */
-    CLK_NONE, /* 111 not defined */
+    CLK_NONE,      /* 000 No clock source */
+    CLK_IPG,       /* 001 ipg_clk, 532MHz*/
+    CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
+    CLK_NONE,      /* 011 not defined */
+    CLK_32k,       /* 100 ipg_clk_32k */
+    CLK_NONE,      /* 101 not defined */
+    CLK_NONE,      /* 110 not defined */
+    CLK_NONE,      /* 111 not defined */
 };
 
 static void imx_gpt_set_freq(IMXGPTState *s)
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 378b78d..48a7afa 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -45,6 +45,7 @@ typedef struct IMXCCMState {
 typedef enum  {
     CLK_NONE,
     CLK_IPG,
+    CLK_IPG_HIGH,
     CLK_32k
 } IMXClk;
 
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device.
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
                   ` (3 preceding siblings ...)
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 4/9] i.MX: Add the CLK_IPG_HIGH clock Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:21   ` Peter Maydell
  2016-02-29 17:33   ` Peter Maydell
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device Jean-Christophe Dubois
                   ` (4 subsequent siblings)
  9 siblings, 2 replies; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

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

Changes since V1:
 * move clk computation to uint64_t to avoid overflow
 * added explanation on _SET, _CLR and _TOG registers
 * move CCM and ANALOG handling in sub memory regions.

 hw/misc/Makefile.objs      |   1 +
 hw/misc/imx6_ccm.c         | 773 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/misc/imx6_ccm.h | 197 ++++++++++++
 3 files changed, 971 insertions(+)
 create mode 100644 hw/misc/imx6_ccm.c
 create mode 100644 include/hw/misc/imx6_ccm.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d4765c2..a2a8e91 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -28,6 +28,7 @@ obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_IMX) += imx25_ccm.o
+obj-$(CONFIG_IMX) += imx6_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/imx6_ccm.c b/hw/misc/imx6_ccm.c
new file mode 100644
index 0000000..8b76c0e
--- /dev/null
+++ b/hw/misc/imx6_ccm.c
@@ -0,0 +1,773 @@
+/*
+ * IMX6 Clock Control Module
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx6_ccm.h"
+
+#ifndef DEBUG_IMX6_CCM
+#define DEBUG_IMX6_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+    do { \
+        if (DEBUG_IMX6_CCM) { \
+            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_CCM, \
+                                             __func__, ##args); \
+        } \
+    } while (0)
+
+static char const *imx6_ccm_reg_name(uint32_t reg)
+{
+    static char unknown[20];
+
+    switch (reg) {
+    case CCM_CCR:
+        return "CCR";
+    case CCM_CCDR:
+        return "CCDR";
+    case CCM_CSR:
+        return "CSR";
+    case CCM_CCSR:
+        return "CCSR";
+    case CCM_CACRR:
+        return "CACRR";
+    case CCM_CBCDR:
+        return "CBCDR";
+    case CCM_CBCMR:
+        return "CBCMR";
+    case CCM_CSCMR1:
+        return "CSCMR1";
+    case CCM_CSCMR2:
+        return "CSCMR2";
+    case CCM_CSCDR1:
+        return "CSCDR1";
+    case CCM_CS1CDR:
+        return "CS1CDR";
+    case CCM_CS2CDR:
+        return "CS2CDR";
+    case CCM_CDCDR:
+        return "CDCDR";
+    case CCM_CHSCCDR:
+        return "CHSCCDR";
+    case CCM_CSCDR2:
+        return "CSCDR2";
+    case CCM_CSCDR3:
+        return "CSCDR3";
+    case CCM_CDHIPR:
+        return "CDHIPR";
+    case CCM_CTOR:
+        return "CTOR";
+    case CCM_CLPCR:
+        return "CLPCR";
+    case CCM_CISR:
+        return "CISR";
+    case CCM_CIMR:
+        return "CIMR";
+    case CCM_CCOSR:
+        return "CCOSR";
+    case CCM_CGPR:
+        return "CGPR";
+    case CCM_CCGR0:
+        return "CCGR0";
+    case CCM_CCGR1:
+        return "CCGR1";
+    case CCM_CCGR2:
+        return "CCGR2";
+    case CCM_CCGR3:
+        return "CCGR3";
+    case CCM_CCGR4:
+        return "CCGR4";
+    case CCM_CCGR5:
+        return "CCGR5";
+    case CCM_CCGR6:
+        return "CCGR6";
+    case CCM_CMEOR:
+        return "CMEOR";
+    default:
+        sprintf(unknown, "%d ?", reg);
+        return unknown;
+    }
+}
+
+static char const *imx6_analog_reg_name(uint32_t reg)
+{
+    static char unknown[20];
+
+    switch (reg) {
+    case CCM_ANALOG_PLL_ARM:
+        return "PLL_ARM";
+    case CCM_ANALOG_PLL_ARM_SET:
+        return "PLL_ARM_SET";
+    case CCM_ANALOG_PLL_ARM_CLR:
+        return "PLL_ARM_CLR";
+    case CCM_ANALOG_PLL_ARM_TOG:
+        return "PLL_ARM_TOG";
+    case CCM_ANALOG_PLL_USB1:
+        return "PLL_USB1";
+    case CCM_ANALOG_PLL_USB1_SET:
+        return "PLL_USB1_SET";
+    case CCM_ANALOG_PLL_USB1_CLR:
+        return "PLL_USB1_CLR";
+    case CCM_ANALOG_PLL_USB1_TOG:
+        return "PLL_USB1_TOG";
+    case CCM_ANALOG_PLL_USB2:
+        return "PLL_USB2";
+    case CCM_ANALOG_PLL_USB2_SET:
+        return "PLL_USB2_SET";
+    case CCM_ANALOG_PLL_USB2_CLR:
+        return "PLL_USB2_CLR";
+    case CCM_ANALOG_PLL_USB2_TOG:
+        return "PLL_USB2_TOG";
+    case CCM_ANALOG_PLL_SYS:
+        return "PLL_SYS";
+    case CCM_ANALOG_PLL_SYS_SET:
+        return "PLL_SYS_SET";
+    case CCM_ANALOG_PLL_SYS_CLR:
+        return "PLL_SYS_CLR";
+    case CCM_ANALOG_PLL_SYS_TOG:
+        return "PLL_SYS_TOG";
+    case CCM_ANALOG_PLL_SYS_SS:
+        return "PLL_SYS_SS";
+    case CCM_ANALOG_PLL_SYS_NUM:
+        return "PLL_SYS_NUM";
+    case CCM_ANALOG_PLL_SYS_DENOM:
+        return "PLL_SYS_DENOM";
+    case CCM_ANALOG_PLL_AUDIO:
+        return "PLL_AUDIO";
+    case CCM_ANALOG_PLL_AUDIO_SET:
+        return "PLL_AUDIO_SET";
+    case CCM_ANALOG_PLL_AUDIO_CLR:
+        return "PLL_AUDIO_CLR";
+    case CCM_ANALOG_PLL_AUDIO_TOG:
+        return "PLL_AUDIO_TOG";
+    case CCM_ANALOG_PLL_AUDIO_NUM:
+        return "PLL_AUDIO_NUM";
+    case CCM_ANALOG_PLL_AUDIO_DENOM:
+        return "PLL_AUDIO_DENOM";
+    case CCM_ANALOG_PLL_VIDEO:
+        return "PLL_VIDEO";
+    case CCM_ANALOG_PLL_VIDEO_SET:
+        return "PLL_VIDEO_SET";
+    case CCM_ANALOG_PLL_VIDEO_CLR:
+        return "PLL_VIDEO_CLR";
+    case CCM_ANALOG_PLL_VIDEO_TOG:
+        return "PLL_VIDEO_TOG";
+    case CCM_ANALOG_PLL_VIDEO_NUM:
+        return "PLL_VIDEO_NUM";
+    case CCM_ANALOG_PLL_VIDEO_DENOM:
+        return "PLL_VIDEO_DENOM";
+    case CCM_ANALOG_PLL_MLB:
+        return "PLL_MLB";
+    case CCM_ANALOG_PLL_MLB_SET:
+        return "PLL_MLB_SET";
+    case CCM_ANALOG_PLL_MLB_CLR:
+        return "PLL_MLB_CLR";
+    case CCM_ANALOG_PLL_MLB_TOG:
+        return "PLL_MLB_TOG";
+    case CCM_ANALOG_PLL_ENET:
+        return "PLL_ENET";
+    case CCM_ANALOG_PLL_ENET_SET:
+        return "PLL_ENET_SET";
+    case CCM_ANALOG_PLL_ENET_CLR:
+        return "PLL_ENET_CLR";
+    case CCM_ANALOG_PLL_ENET_TOG:
+        return "PLL_ENET_TOG";
+    case CCM_ANALOG_PFD_480:
+        return "PFD_480";
+    case CCM_ANALOG_PFD_480_SET:
+        return "PFD_480_SET";
+    case CCM_ANALOG_PFD_480_CLR:
+        return "PFD_480_CLR";
+    case CCM_ANALOG_PFD_480_TOG:
+        return "PFD_480_TOG";
+    case CCM_ANALOG_PFD_528:
+        return "PFD_528";
+    case CCM_ANALOG_PFD_528_SET:
+        return "PFD_528_SET";
+    case CCM_ANALOG_PFD_528_CLR:
+        return "PFD_528_CLR";
+    case CCM_ANALOG_PFD_528_TOG:
+        return "PFD_528_TOG";
+    case CCM_ANALOG_MISC0:
+        return "MISC0";
+    case CCM_ANALOG_MISC0_SET:
+        return "MISC0_SET";
+    case CCM_ANALOG_MISC0_CLR:
+        return "MISC0_CLR";
+    case CCM_ANALOG_MISC0_TOG:
+        return "MISC0_TOG";
+    case CCM_ANALOG_MISC2:
+        return "MISC2";
+    case CCM_ANALOG_MISC2_SET:
+        return "MISC2_SET";
+    case CCM_ANALOG_MISC2_CLR:
+        return "MISC2_CLR";
+    case CCM_ANALOG_MISC2_TOG:
+        return "MISC2_TOG";
+    case PMU_REG_1P1:
+        return "PMU_REG_1P1";
+    case PMU_REG_3P0:
+        return "PMU_REG_3P0";
+    case PMU_REG_2P5:
+        return "PMU_REG_2P5";
+    case PMU_REG_CORE:
+        return "PMU_REG_CORE";
+    case PMU_MISC1:
+        return "PMU_MISC1";
+    case PMU_MISC1_SET:
+        return "PMU_MISC1_SET";
+    case PMU_MISC1_CLR:
+        return "PMU_MISC1_CLR";
+    case PMU_MISC1_TOG:
+        return "PMU_MISC1_TOG";
+    case USB_ANALOG_DIGPROG:
+        return "USB_ANALOG_DIGPROG";
+    default:
+        sprintf(unknown, "%d ?", reg);
+        return unknown;
+    }
+}
+
+#define CKIH_FREQ 24000000 /* 24MHz crystal input */
+
+static const VMStateDescription vmstate_imx6_ccm = {
+    .name = TYPE_IMX6_CCM,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(ccm, IMX6CCMState, CCM_MAX),
+        VMSTATE_UINT32_ARRAY(analog, IMX6CCMState, CCM_ANALOG_MAX),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static uint64_t imx6_analog_get_pll2_clk(IMX6CCMState *dev)
+{
+    uint64_t freq = 24000000;
+
+    if (EXTRACT(dev->analog[CCM_ANALOG_PLL_SYS], DIV_SELECT)) {
+        freq *= 22;
+    } else {
+        freq *= 20;
+    }
+
+    DPRINTF("freq = %d\n", (uint32_t)freq);
+
+    return freq;
+}
+
+static uint64_t imx6_analog_get_pll2_pfd0_clk(IMX6CCMState *dev)
+{
+    uint64_t freq = 0;
+
+    freq = imx6_analog_get_pll2_clk(dev) * 18
+           / EXTRACT(dev->analog[CCM_ANALOG_PFD_528], PFD0_FRAC);
+
+    DPRINTF("freq = %d\n", (uint32_t)freq);
+
+    return freq;
+}
+
+static uint64_t imx6_analog_get_pll2_pfd2_clk(IMX6CCMState *dev)
+{
+    uint64_t freq = 0;
+
+    freq = imx6_analog_get_pll2_clk(dev) * 18
+           / EXTRACT(dev->analog[CCM_ANALOG_PFD_528], PFD2_FRAC);
+
+    DPRINTF("freq = %d\n", (uint32_t)freq);
+
+    return freq;
+}
+
+static uint64_t imx6_analog_get_periph_clk(IMX6CCMState *dev)
+{
+    uint64_t freq = 0;
+
+    switch (EXTRACT(dev->ccm[CCM_CBCMR], PRE_PERIPH_CLK_SEL)) {
+    case 0:
+        freq = imx6_analog_get_pll2_clk(dev);
+        break;
+    case 1:
+        freq = imx6_analog_get_pll2_pfd2_clk(dev);
+        break;
+    case 2:
+        freq = imx6_analog_get_pll2_pfd0_clk(dev);
+        break;
+    case 3:
+        freq = imx6_analog_get_pll2_pfd2_clk(dev) / 2;
+        break;
+    default:
+        /* We should never get there */
+        g_assert_not_reached();
+        break;
+    }
+
+    DPRINTF("freq = %d\n", (uint32_t)freq);
+
+    return freq;
+}
+
+static uint64_t imx6_ccm_get_ahb_clk(IMX6CCMState *dev)
+{
+    uint64_t freq = 0;
+
+    freq = imx6_analog_get_periph_clk(dev)
+           / (1 + EXTRACT(dev->ccm[CCM_CBCDR], AHB_PODF));
+
+    DPRINTF("freq = %d\n", (uint32_t)freq);
+
+    return freq;
+}
+
+static uint64_t imx6_ccm_get_ipg_clk(IMX6CCMState *dev)
+{
+    uint64_t freq = 0;
+
+    freq = imx6_ccm_get_ahb_clk(dev)
+           / (1 + EXTRACT(dev->ccm[CCM_CBCDR], IPG_PODF));;
+
+    DPRINTF("freq = %d\n", (uint32_t)freq);
+
+    return freq;
+}
+
+static uint64_t imx6_ccm_get_per_clk(IMX6CCMState *dev)
+{
+    uint64_t freq = 0;
+
+    freq = imx6_ccm_get_ipg_clk(dev)
+           / (1 + EXTRACT(dev->ccm[CCM_CSCMR1], PERCLK_PODF));
+
+    DPRINTF("freq = %d\n", (uint32_t)freq);
+
+    return freq;
+}
+
+static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
+{
+    uint32_t freq = 0;
+    IMX6CCMState *s = IMX6_CCM(dev);
+
+    switch (clock) {
+    case CLK_NONE:
+        break;
+    case CLK_IPG:
+        freq = imx6_ccm_get_ipg_clk(s);
+        break;
+    case CLK_IPG_HIGH:
+        freq = imx6_ccm_get_per_clk(s);
+        break;
+    case CLK_32k:
+        freq = CKIL_FREQ;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
+                      TYPE_IMX6_CCM, __func__, clock);
+        break;
+    }
+
+    DPRINTF("Clock = %d) = %d\n", clock, freq);
+
+    return freq;
+}
+
+static void imx6_ccm_reset(DeviceState *dev)
+{
+    IMX6CCMState *s = IMX6_CCM(dev);
+
+    DPRINTF("\n");
+
+    s->ccm[CCM_CCR] = 0x040116FF;
+    s->ccm[CCM_CCDR] = 0x00000000;
+    s->ccm[CCM_CSR] = 0x00000010;
+    s->ccm[CCM_CCSR] = 0x00000100;
+    s->ccm[CCM_CACRR] = 0x00000000;
+    s->ccm[CCM_CBCDR] = 0x00018D40;
+    s->ccm[CCM_CBCMR] = 0x00022324;
+    s->ccm[CCM_CSCMR1] = 0x00F00000;
+    s->ccm[CCM_CSCMR2] = 0x02B92F06;
+    s->ccm[CCM_CSCDR1] = 0x00490B00;
+    s->ccm[CCM_CS1CDR] = 0x0EC102C1;
+    s->ccm[CCM_CS2CDR] = 0x000736C1;
+    s->ccm[CCM_CDCDR] = 0x33F71F92;
+    s->ccm[CCM_CHSCCDR] = 0x0002A150;
+    s->ccm[CCM_CSCDR2] = 0x0002A150;
+    s->ccm[CCM_CSCDR3] = 0x00014841;
+    s->ccm[CCM_CDHIPR] = 0x00000000;
+    s->ccm[CCM_CTOR] = 0x00000000;
+    s->ccm[CCM_CLPCR] = 0x00000079;
+    s->ccm[CCM_CISR] = 0x00000000;
+    s->ccm[CCM_CIMR] = 0xFFFFFFFF;
+    s->ccm[CCM_CCOSR] = 0x000A0001;
+    s->ccm[CCM_CGPR] = 0x0000FE62;
+    s->ccm[CCM_CCGR0] = 0xFFFFFFFF;
+    s->ccm[CCM_CCGR1] = 0xFFFFFFFF;
+    s->ccm[CCM_CCGR2] = 0xFC3FFFFF;
+    s->ccm[CCM_CCGR3] = 0xFFFFFFFF;
+    s->ccm[CCM_CCGR4] = 0xFFFFFFFF;
+    s->ccm[CCM_CCGR5] = 0xFFFFFFFF;
+    s->ccm[CCM_CCGR6] = 0xFFFFFFFF;
+    s->ccm[CCM_CMEOR] = 0xFFFFFFFF;
+
+    s->analog[CCM_ANALOG_PLL_ARM] = 0x00013042;
+    s->analog[CCM_ANALOG_PLL_USB1] = 0x00012000;
+    s->analog[CCM_ANALOG_PLL_USB2] = 0x00012000;
+    s->analog[CCM_ANALOG_PLL_SYS] = 0x00013001;
+    s->analog[CCM_ANALOG_PLL_SYS_SS] = 0x00000000;
+    s->analog[CCM_ANALOG_PLL_SYS_NUM] = 0x00000000;
+    s->analog[CCM_ANALOG_PLL_SYS_DENOM] = 0x00000012;
+    s->analog[CCM_ANALOG_PLL_AUDIO] = 0x00011006;
+    s->analog[CCM_ANALOG_PLL_AUDIO_NUM] = 0x05F5E100;
+    s->analog[CCM_ANALOG_PLL_AUDIO_DENOM] = 0x2964619C;
+    s->analog[CCM_ANALOG_PLL_VIDEO] = 0x0001100C;
+    s->analog[CCM_ANALOG_PLL_VIDEO_NUM] = 0x05F5E100;
+    s->analog[CCM_ANALOG_PLL_VIDEO_DENOM] = 0x10A24447;
+    s->analog[CCM_ANALOG_PLL_MLB] = 0x00010000;
+    s->analog[CCM_ANALOG_PLL_ENET] = 0x00011001;
+    s->analog[CCM_ANALOG_PFD_480] = 0x1311100C;
+    s->analog[CCM_ANALOG_PFD_528] = 0x1018101B;
+
+    s->analog[PMU_REG_1P1] = 0x00001073;
+    s->analog[PMU_REG_3P0] = 0x00000F74;
+    s->analog[PMU_REG_2P5] = 0x00005071;
+    s->analog[PMU_REG_CORE] = 0x00402010;
+    s->analog[PMU_MISC0] = 0x04000000;
+    s->analog[PMU_MISC1] = 0x00000000;
+    s->analog[PMU_MISC2] = 0x00272727;
+
+    s->analog[USB_ANALOG_USB1_VBUS_DETECT] = 0x00000004;
+    s->analog[USB_ANALOG_USB1_CHRG_DETECT] = 0x00000000;
+    s->analog[USB_ANALOG_USB1_VBUS_DETECT_STAT] = 0x00000000;
+    s->analog[USB_ANALOG_USB1_CHRG_DETECT_STAT] = 0x00000000;
+    s->analog[USB_ANALOG_USB1_MISC] = 0x00000002;
+    s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x00000004;
+    s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
+    s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
+    s->analog[USB_ANALOG_DIGPROG] = 0x00000000;
+
+    /* all PLLs need to be locked */
+    s->analog[CCM_ANALOG_PLL_ARM]   |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_USB1]  |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_USB2]  |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_SYS]   |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_AUDIO] |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_VIDEO] |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_MLB]   |= CCM_ANALOG_PLL_LOCK;
+    s->analog[CCM_ANALOG_PLL_ENET]  |= CCM_ANALOG_PLL_LOCK;
+}
+
+static uint64_t imx6_ccm_read(void *opaque, hwaddr offset, unsigned size)
+{
+    uint32 value = 0;
+    uint32_t index = offset >> 2;
+    IMX6CCMState *s = (IMX6CCMState *)opaque;
+
+    value = s->ccm[index];
+
+    DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx6_ccm_reg_name(index), value);
+
+    return (uint64_t)value;
+}
+
+static void imx6_ccm_write(void *opaque, hwaddr offset, uint64_t value,
+                           unsigned size)
+{
+    uint32_t index = offset >> 2;
+    IMX6CCMState *s = (IMX6CCMState *)opaque;
+
+    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx6_ccm_reg_name(index),
+            (uint32_t)value);
+
+    /*
+     * We will do a better implementation later. In particular some bits
+     * cannot be written to.
+     */
+    s->ccm[index] = (uint32_t)value;
+}
+
+static uint64_t imx6_analog_read(void *opaque, hwaddr offset, unsigned size)
+{
+    uint32_t value;
+    uint32_t index = offset >> 2;
+    IMX6CCMState *s = (IMX6CCMState *)opaque;
+
+    switch (index) {
+    case CCM_ANALOG_PLL_ARM_SET:
+    case CCM_ANALOG_PLL_USB1_SET:
+    case CCM_ANALOG_PLL_USB2_SET:
+    case CCM_ANALOG_PLL_SYS_SET:
+    case CCM_ANALOG_PLL_AUDIO_SET:
+    case CCM_ANALOG_PLL_VIDEO_SET:
+    case CCM_ANALOG_PLL_MLB_SET:
+    case CCM_ANALOG_PLL_ENET_SET:
+    case CCM_ANALOG_PFD_480_SET:
+    case CCM_ANALOG_PFD_528_SET:
+    case CCM_ANALOG_MISC0_SET:
+    case PMU_MISC1_SET:
+    case CCM_ANALOG_MISC2_SET:
+    case USB_ANALOG_USB1_VBUS_DETECT_SET:
+    case USB_ANALOG_USB1_CHRG_DETECT_SET:
+    case USB_ANALOG_USB1_MISC_SET:
+    case USB_ANALOG_USB2_VBUS_DETECT_SET:
+    case USB_ANALOG_USB2_CHRG_DETECT_SET:
+    case USB_ANALOG_USB2_MISC_SET:
+        /*
+         * All REG_NAME_SET register access are in fact targeting the
+         * the REG_NAME register.
+         */
+        value = s->analog[index - 1];
+        break;
+    case CCM_ANALOG_PLL_ARM_CLR:
+    case CCM_ANALOG_PLL_USB1_CLR:
+    case CCM_ANALOG_PLL_USB2_CLR:
+    case CCM_ANALOG_PLL_SYS_CLR:
+    case CCM_ANALOG_PLL_AUDIO_CLR:
+    case CCM_ANALOG_PLL_VIDEO_CLR:
+    case CCM_ANALOG_PLL_MLB_CLR:
+    case CCM_ANALOG_PLL_ENET_CLR:
+    case CCM_ANALOG_PFD_480_CLR:
+    case CCM_ANALOG_PFD_528_CLR:
+    case CCM_ANALOG_MISC0_CLR:
+    case PMU_MISC1_CLR:
+    case CCM_ANALOG_MISC2_CLR:
+    case USB_ANALOG_USB1_VBUS_DETECT_CLR:
+    case USB_ANALOG_USB1_CHRG_DETECT_CLR:
+    case USB_ANALOG_USB1_MISC_CLR:
+    case USB_ANALOG_USB2_VBUS_DETECT_CLR:
+    case USB_ANALOG_USB2_CHRG_DETECT_CLR:
+    case USB_ANALOG_USB2_MISC_CLR:
+        /*
+         * All REG_NAME_CLR register access are in fact targeting the
+         * the REG_NAME register.
+         */
+        value = s->analog[index - 2];
+        break;
+    case CCM_ANALOG_PLL_ARM_TOG:
+    case CCM_ANALOG_PLL_USB1_TOG:
+    case CCM_ANALOG_PLL_USB2_TOG:
+    case CCM_ANALOG_PLL_SYS_TOG:
+    case CCM_ANALOG_PLL_AUDIO_TOG:
+    case CCM_ANALOG_PLL_VIDEO_TOG:
+    case CCM_ANALOG_PLL_MLB_TOG:
+    case CCM_ANALOG_PLL_ENET_TOG:
+    case CCM_ANALOG_PFD_480_TOG:
+    case CCM_ANALOG_PFD_528_TOG:
+    case CCM_ANALOG_MISC0_TOG:
+    case PMU_MISC1_TOG:
+    case CCM_ANALOG_MISC2_TOG:
+    case USB_ANALOG_USB1_VBUS_DETECT_TOG:
+    case USB_ANALOG_USB1_CHRG_DETECT_TOG:
+    case USB_ANALOG_USB1_MISC_TOG:
+    case USB_ANALOG_USB2_VBUS_DETECT_TOG:
+    case USB_ANALOG_USB2_CHRG_DETECT_TOG:
+    case USB_ANALOG_USB2_MISC_TOG:
+        /*
+         * All REG_NAME_TOG register access are in fact targeting the
+         * the REG_NAME register.
+         */
+        value = s->analog[index - 3];
+        break;
+    default:
+        value = s->analog[index];
+        break;
+    }
+
+    DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx6_analog_reg_name(index), value);
+
+    return (uint64_t)value;
+}
+
+static void imx6_analog_write(void *opaque, hwaddr offset, uint64_t value,
+                              unsigned size)
+{
+    uint32_t index = offset >> 2;
+    IMX6CCMState *s = (IMX6CCMState *)opaque;
+
+    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx6_analog_reg_name(index),
+            (uint32_t)value);
+
+    switch (index) {
+    case CCM_ANALOG_PLL_ARM_SET:
+    case CCM_ANALOG_PLL_USB1_SET:
+    case CCM_ANALOG_PLL_USB2_SET:
+    case CCM_ANALOG_PLL_SYS_SET:
+    case CCM_ANALOG_PLL_AUDIO_SET:
+    case CCM_ANALOG_PLL_VIDEO_SET:
+    case CCM_ANALOG_PLL_MLB_SET:
+    case CCM_ANALOG_PLL_ENET_SET:
+    case CCM_ANALOG_PFD_480_SET:
+    case CCM_ANALOG_PFD_528_SET:
+    case CCM_ANALOG_MISC0_SET:
+    case PMU_MISC1_SET:
+    case CCM_ANALOG_MISC2_SET:
+    case USB_ANALOG_USB1_VBUS_DETECT_SET:
+    case USB_ANALOG_USB1_CHRG_DETECT_SET:
+    case USB_ANALOG_USB1_MISC_SET:
+    case USB_ANALOG_USB2_VBUS_DETECT_SET:
+    case USB_ANALOG_USB2_CHRG_DETECT_SET:
+    case USB_ANALOG_USB2_MISC_SET:
+        /*
+         * All REG_NAME_SET register access are in fact targeting the
+         * the REG_NAME register. So we change the value of the
+         * REG_NAME register, setting bits passed in the value.
+         */
+        s->analog[index - 1] |= value;
+        break;
+    case CCM_ANALOG_PLL_ARM_CLR:
+    case CCM_ANALOG_PLL_USB1_CLR:
+    case CCM_ANALOG_PLL_USB2_CLR:
+    case CCM_ANALOG_PLL_SYS_CLR:
+    case CCM_ANALOG_PLL_AUDIO_CLR:
+    case CCM_ANALOG_PLL_VIDEO_CLR:
+    case CCM_ANALOG_PLL_MLB_CLR:
+    case CCM_ANALOG_PLL_ENET_CLR:
+    case CCM_ANALOG_PFD_480_CLR:
+    case CCM_ANALOG_PFD_528_CLR:
+    case CCM_ANALOG_MISC0_CLR:
+    case PMU_MISC1_CLR:
+    case CCM_ANALOG_MISC2_CLR:
+    case USB_ANALOG_USB1_VBUS_DETECT_CLR:
+    case USB_ANALOG_USB1_CHRG_DETECT_CLR:
+    case USB_ANALOG_USB1_MISC_CLR:
+    case USB_ANALOG_USB2_VBUS_DETECT_CLR:
+    case USB_ANALOG_USB2_CHRG_DETECT_CLR:
+    case USB_ANALOG_USB2_MISC_CLR:
+        /*
+         * All REG_NAME_CLR register access are in fact targeting the
+         * the REG_NAME register. So we change the value of the
+         * REG_NAME register, unsetting bits passed in the value.
+         */
+        s->analog[index - 2] &= ~value;
+        break;
+    case CCM_ANALOG_PLL_ARM_TOG:
+    case CCM_ANALOG_PLL_USB1_TOG:
+    case CCM_ANALOG_PLL_USB2_TOG:
+    case CCM_ANALOG_PLL_SYS_TOG:
+    case CCM_ANALOG_PLL_AUDIO_TOG:
+    case CCM_ANALOG_PLL_VIDEO_TOG:
+    case CCM_ANALOG_PLL_MLB_TOG:
+    case CCM_ANALOG_PLL_ENET_TOG:
+    case CCM_ANALOG_PFD_480_TOG:
+    case CCM_ANALOG_PFD_528_TOG:
+    case CCM_ANALOG_MISC0_TOG:
+    case PMU_MISC1_TOG:
+    case CCM_ANALOG_MISC2_TOG:
+    case USB_ANALOG_USB1_VBUS_DETECT_TOG:
+    case USB_ANALOG_USB1_CHRG_DETECT_TOG:
+    case USB_ANALOG_USB1_MISC_TOG:
+    case USB_ANALOG_USB2_VBUS_DETECT_TOG:
+    case USB_ANALOG_USB2_CHRG_DETECT_TOG:
+    case USB_ANALOG_USB2_MISC_TOG:
+        /*
+         * All REG_NAME_TOG register access are in fact targeting the
+         * the REG_NAME register. So we change the value of the
+         * REG_NAME register, toggling bits passed in the value.
+         */
+        s->analog[index - 3] ^= value;
+        break;
+    default:
+        /*
+         * We will do a better implementation later. In particular some bits
+         * cannot be written to.
+         */
+        s->analog[index] = value;
+        break;
+    }
+}
+
+static const struct MemoryRegionOps imx6_ccm_ops = {
+    .read = imx6_ccm_read,
+    .write = imx6_ccm_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        /*
+         * 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 const struct MemoryRegionOps imx6_analog_ops = {
+    .read = imx6_analog_read,
+    .write = imx6_analog_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        /*
+         * 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 imx6_ccm_init(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    SysBusDevice *sd = SYS_BUS_DEVICE(obj);
+    IMX6CCMState *s = IMX6_CCM(obj);
+
+    /* initialize a container for the all memory range */
+    memory_region_init(&s->container, OBJECT(dev), TYPE_IMX6_CCM, 0x5000);
+
+    /* We initialize an IO memory region for the CCM part */
+    memory_region_init_io(&s->ioccm, OBJECT(dev), &imx6_ccm_ops, s,
+                          TYPE_IMX6_CCM ".ccm", CCM_MAX * sizeof(uint32_t));
+
+    /* Add the CCM as a subregion at offset 0 */
+    memory_region_add_subregion(&s->container, 0, &s->ioccm);
+
+    /* We initialize an IO memory region for the ANALOG part */
+    memory_region_init_io(&s->ioanalog, OBJECT(dev), &imx6_analog_ops, s,
+                          TYPE_IMX6_CCM ".analog",
+                          CCM_ANALOG_MAX * sizeof(uint32_t));
+
+    /* Add the ANALOG as a subregion at offset 0x4000 */
+    memory_region_add_subregion(&s->container, 0x4000, &s->ioanalog);
+
+    sysbus_init_mmio(sd, &s->container);
+}
+
+static void imx6_ccm_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
+
+    dc->reset = imx6_ccm_reset;
+    dc->vmsd = &vmstate_imx6_ccm;
+    dc->desc = "i.MX6 Clock Control Module";
+
+    ccm->get_clock_frequency = imx6_ccm_get_clock_frequency;
+}
+
+static const TypeInfo imx6_ccm_info = {
+    .name          = TYPE_IMX6_CCM,
+    .parent        = TYPE_IMX_CCM,
+    .instance_size = sizeof(IMX6CCMState),
+    .instance_init = imx6_ccm_init,
+    .class_init    = imx6_ccm_class_init,
+};
+
+static void imx6_ccm_register_types(void)
+{
+    type_register_static(&imx6_ccm_info);
+}
+
+type_init(imx6_ccm_register_types)
diff --git a/include/hw/misc/imx6_ccm.h b/include/hw/misc/imx6_ccm.h
new file mode 100644
index 0000000..8050580
--- /dev/null
+++ b/include/hw/misc/imx6_ccm.h
@@ -0,0 +1,197 @@
+/*
+ * IMX6 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * 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 IMX6_CCM_H
+#define IMX6_CCM_H
+
+#include "hw/misc/imx_ccm.h"
+#include "qemu/bitops.h"
+
+#define CCM_CCR 0
+#define CCM_CCDR 1
+#define CCM_CSR 2
+#define CCM_CCSR 3
+#define CCM_CACRR 4
+#define CCM_CBCDR 5
+#define CCM_CBCMR 6
+#define CCM_CSCMR1 7
+#define CCM_CSCMR2 8
+#define CCM_CSCDR1 9
+#define CCM_CS1CDR 10
+#define CCM_CS2CDR 11
+#define CCM_CDCDR 12
+#define CCM_CHSCCDR 13
+#define CCM_CSCDR2 14
+#define CCM_CSCDR3 15
+#define CCM_CDHIPR 18
+#define CCM_CTOR 20
+#define CCM_CLPCR 21
+#define CCM_CISR 22
+#define CCM_CIMR 23
+#define CCM_CCOSR 24
+#define CCM_CGPR 25
+#define CCM_CCGR0 26
+#define CCM_CCGR1 27
+#define CCM_CCGR2 28
+#define CCM_CCGR3 29
+#define CCM_CCGR4 30
+#define CCM_CCGR5 31
+#define CCM_CCGR6 32
+#define CCM_CMEOR 34
+#define CCM_MAX 35
+
+#define CCM_ANALOG_PLL_ARM 0
+#define CCM_ANALOG_PLL_ARM_SET 1
+#define CCM_ANALOG_PLL_ARM_CLR 2
+#define CCM_ANALOG_PLL_ARM_TOG 3
+#define CCM_ANALOG_PLL_USB1 4
+#define CCM_ANALOG_PLL_USB1_SET 5
+#define CCM_ANALOG_PLL_USB1_CLR 6
+#define CCM_ANALOG_PLL_USB1_TOG 7
+#define CCM_ANALOG_PLL_USB2 8
+#define CCM_ANALOG_PLL_USB2_SET 9
+#define CCM_ANALOG_PLL_USB2_CLR 10
+#define CCM_ANALOG_PLL_USB2_TOG 11
+#define CCM_ANALOG_PLL_SYS 12
+#define CCM_ANALOG_PLL_SYS_SET 13
+#define CCM_ANALOG_PLL_SYS_CLR 14
+#define CCM_ANALOG_PLL_SYS_TOG 15
+#define CCM_ANALOG_PLL_SYS_SS 16
+#define CCM_ANALOG_PLL_SYS_NUM 20
+#define CCM_ANALOG_PLL_SYS_DENOM 24
+#define CCM_ANALOG_PLL_AUDIO 28
+#define CCM_ANALOG_PLL_AUDIO_SET 29
+#define CCM_ANALOG_PLL_AUDIO_CLR 30
+#define CCM_ANALOG_PLL_AUDIO_TOG 31
+#define CCM_ANALOG_PLL_AUDIO_NUM 32
+#define CCM_ANALOG_PLL_AUDIO_DENOM 36
+#define CCM_ANALOG_PLL_VIDEO 40
+#define CCM_ANALOG_PLL_VIDEO_SET 41
+#define CCM_ANALOG_PLL_VIDEO_CLR 42
+#define CCM_ANALOG_PLL_VIDEO_TOG 44
+#define CCM_ANALOG_PLL_VIDEO_NUM 46
+#define CCM_ANALOG_PLL_VIDEO_DENOM 48
+#define CCM_ANALOG_PLL_MLB 52
+#define CCM_ANALOG_PLL_MLB_SET 53
+#define CCM_ANALOG_PLL_MLB_CLR 54
+#define CCM_ANALOG_PLL_MLB_TOG 55
+#define CCM_ANALOG_PLL_ENET 56
+#define CCM_ANALOG_PLL_ENET_SET 57
+#define CCM_ANALOG_PLL_ENET_CLR 58
+#define CCM_ANALOG_PLL_ENET_TOG 59
+#define CCM_ANALOG_PFD_480 60
+#define CCM_ANALOG_PFD_480_SET 61
+#define CCM_ANALOG_PFD_480_CLR 62
+#define CCM_ANALOG_PFD_480_TOG 63
+#define CCM_ANALOG_PFD_528 64
+#define CCM_ANALOG_PFD_528_SET 65
+#define CCM_ANALOG_PFD_528_CLR 66
+#define CCM_ANALOG_PFD_528_TOG 67
+
+/* PMU registers */
+#define PMU_REG_1P1 68
+#define PMU_REG_3P0 72
+#define PMU_REG_2P5 76
+#define PMU_REG_CORE 80
+
+#define CCM_ANALOG_MISC0 84
+#define PMU_MISC0 84
+#define CCM_ANALOG_MISC0_SET 85
+#define CCM_ANALOG_MISC0_CLR 86
+#define CCM_ANALOG_MISC0_TOG 87
+
+#define PMU_MISC1 88
+#define PMU_MISC1_SET 89
+#define PMU_MISC1_CLR 90
+#define PMU_MISC1_TOG 91
+
+#define CCM_ANALOG_MISC2 92
+#define PMU_MISC2 92
+#define CCM_ANALOG_MISC2_SET 93
+#define CCM_ANALOG_MISC2_CLR 94
+#define CCM_ANALOG_MISC2_TOG 95
+
+#define USB_ANALOG_USB1_VBUS_DETECT 104
+#define USB_ANALOG_USB1_VBUS_DETECT_SET 105
+#define USB_ANALOG_USB1_VBUS_DETECT_CLR 106
+#define USB_ANALOG_USB1_VBUS_DETECT_TOG 107
+#define USB_ANALOG_USB1_CHRG_DETECT 108
+#define USB_ANALOG_USB1_CHRG_DETECT_SET 109
+#define USB_ANALOG_USB1_CHRG_DETECT_CLR 110
+#define USB_ANALOG_USB1_CHRG_DETECT_TOG 111
+#define USB_ANALOG_USB1_VBUS_DETECT_STAT 112
+#define USB_ANALOG_USB1_CHRG_DETECT_STAT 116
+#define USB_ANALOG_USB1_MISC 124
+#define USB_ANALOG_USB1_MISC_SET 125
+#define USB_ANALOG_USB1_MISC_CLR 126
+#define USB_ANALOG_USB1_MISC_TOG 127
+#define USB_ANALOG_USB2_VBUS_DETECT 128
+#define USB_ANALOG_USB2_VBUS_DETECT_SET 129
+#define USB_ANALOG_USB2_VBUS_DETECT_CLR 130
+#define USB_ANALOG_USB2_VBUS_DETECT_TOG 131
+#define USB_ANALOG_USB2_CHRG_DETECT 132
+#define USB_ANALOG_USB2_CHRG_DETECT_SET 133
+#define USB_ANALOG_USB2_CHRG_DETECT_CLR 134
+#define USB_ANALOG_USB2_CHRG_DETECT_TOG 135
+#define USB_ANALOG_USB2_VBUS_DETECT_STAT 136
+#define USB_ANALOG_USB2_CHRG_DETECT_STAT 140
+#define USB_ANALOG_USB2_MISC 148
+#define USB_ANALOG_USB2_MISC_SET 149
+#define USB_ANALOG_USB2_MISC_CLR 150
+#define USB_ANALOG_USB2_MISC_TOG 151
+#define USB_ANALOG_DIGPROG 152
+#define CCM_ANALOG_MAX 153
+
+/* CCM_CBCMR */
+#define PRE_PERIPH_CLK_SEL_SHIFT  (18)
+#define PRE_PERIPH_CLK_SEL_LENGTH (2)
+
+/* CCM_CBCDR */
+#define AHB_PODF_SHIFT           (10)
+#define AHB_PODF_LENGTH          (3)
+#define IPG_PODF_SHIFT           (8)
+#define IPG_PODF_LENGTH          (2)
+
+/* CCM_CSCMR1 */
+#define PERCLK_PODF_SHIFT        (0)
+#define PERCLK_PODF_LENGTH       (6)
+
+/* CCM_ANALOG_PFD_528 */
+#define PFD0_FRAC_SHIFT          (0)
+#define PFD0_FRAC_LENGTH         (6)
+#define PFD2_FRAC_SHIFT          (16)
+#define PFD2_FRAC_LENGTH         (6)
+
+/* CCM_ANALOG_PLL_SYS */
+#define DIV_SELECT_SHIFT         (0)
+#define DIV_SELECT_LENGTH        (1)
+
+#define CCM_ANALOG_PLL_LOCK      (1 << 31);
+
+#define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH)
+
+#define TYPE_IMX6_CCM "imx6.ccm"
+#define IMX6_CCM(obj) OBJECT_CHECK(IMX6CCMState, (obj), TYPE_IMX6_CCM)
+
+typedef struct IMX6CCMState {
+    /* <private> */
+    IMXCCMState parent_obj;
+
+    /* <public> */
+    MemoryRegion container;
+    MemoryRegion ioccm;
+    MemoryRegion ioanalog;
+
+    uint32_t ccm[CCM_MAX];
+    uint32_t analog[CCM_ANALOG_MAX];
+
+} IMX6CCMState;
+
+#endif /* IMX6_CCM_H */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device.
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
                   ` (4 preceding siblings ...)
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:35   ` Peter Maydell
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation Jean-Christophe Dubois
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

This controller is also present in i.MX5X devices but they are not
yet emulated by QEMU.

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

Changes since V1:
 * Change "reset" sematic to mean full power cyvle.

 hw/misc/Makefile.objs      |   1 +
 hw/misc/imx6_src.c         | 353 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/misc/imx6_src.h |  73 ++++++++++
 3 files changed, 427 insertions(+)
 create mode 100644 hw/misc/imx6_src.c
 create mode 100644 include/hw/misc/imx6_src.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index a2a8e91..6bac654 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -29,6 +29,7 @@ obj-$(CONFIG_IMX) += imx_ccm.o
 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_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c
new file mode 100644
index 0000000..2cf97ef
--- /dev/null
+++ b/hw/misc/imx6_src.c
@@ -0,0 +1,353 @@
+/*
+ * IMX6 System Reset Controller
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * 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 "hw/misc/imx6_src.h"
+#include "sysemu/sysemu.h"
+#include "qemu/bitops.h"
+
+#ifndef DEBUG_IMX6_SRC
+#define DEBUG_IMX6_SRC 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+    do { \
+        if (DEBUG_IMX6_SRC) { \
+            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX6_SRC, \
+                                             __func__, ##args); \
+        } \
+    } while (0)
+
+static char const *imx6_src_reg_name(uint32_t reg)
+{
+    static char unknown[20];
+
+    switch (reg) {
+    case SRC_SCR:
+        return "SRC_SCR";
+    case SRC_SBMR1:
+        return "SRC_SBMR1";
+    case SRC_SRSR:
+        return "SRC_SRSR";
+    case SRC_SISR:
+        return "SRC_SISR";
+    case SRC_SIMR:
+        return "SRC_SIMR";
+    case SRC_SBMR2:
+        return "SRC_SBMR2";
+    case SRC_GPR1:
+        return "SRC_GPR1";
+    case SRC_GPR2:
+        return "SRC_GPR2";
+    case SRC_GPR3:
+        return "SRC_GPR3";
+    case SRC_GPR4:
+        return "SRC_GPR4";
+    case SRC_GPR5:
+        return "SRC_GPR5";
+    case SRC_GPR6:
+        return "SRC_GPR6";
+    case SRC_GPR7:
+        return "SRC_GPR7";
+    case SRC_GPR8:
+        return "SRC_GPR8";
+    case SRC_GPR9:
+        return "SRC_GPR9";
+    case SRC_GPR10:
+        return "SRC_GPR10";
+    default:
+        sprintf(unknown, "%d ?", reg);
+        return unknown;
+    }
+}
+
+static const VMStateDescription vmstate_imx6_src = {
+    .name = TYPE_IMX6_SRC,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, IMX6SRCState, SRC_MAX),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static void imx6_src_reset(DeviceState *dev)
+{
+    IMX6SRCState *s = IMX6_SRC(dev);
+
+    DPRINTF("\n");
+
+    /*
+     * We only clear the first registers as all GPR registers are preserved
+     * over resets
+     */
+    memset(s->regs, 0, SRC_MAX * sizeof(uint32_t));
+
+    /* Set reset values */
+    s->regs[SRC_SCR] = 0x521;
+    s->regs[SRC_SRSR] = 0x1;
+    s->regs[SRC_SIMR] = 0x1F;
+}
+
+static CPUState *imx6_src_get_cpu_by_id(uint32_t id)
+{
+    CPUState *cpu;
+
+    DPRINTF("cpu %d\n", id);
+
+    CPU_FOREACH(cpu) {
+        ARMCPU *armcpu = ARM_CPU(cpu);
+
+        if (armcpu->mp_affinity == id) {
+            return cpu;
+        }
+    }
+
+    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Resquesting unknown CPU %d\n",
+                  TYPE_IMX6_SRC, __func__, id);
+
+    return NULL;
+}
+
+static void imx6_src_cpu_on(uint32_t cpuid, uint32_t entry, uint32_t context_id)
+{
+    CPUState *target_cpu_state;
+    ARMCPU *target_cpu;
+    CPUClass *target_cpu_class;
+
+    DPRINTF("cpu %d @ 0x%08x with R0 = 0x%08x\n", cpuid, entry, context_id);
+
+    /* change to the cpu we are powering up */
+    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
+    if (!target_cpu_state) {
+        return;
+    }
+    target_cpu = ARM_CPU(target_cpu_state);
+    if (!target_cpu->powered_off) {
+        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already running\n",
+                      TYPE_IMX6_SRC, __func__, cpuid);
+        return;
+    }
+    target_cpu_class = CPU_GET_CLASS(target_cpu);
+
+    /* Initialize the cpu we are turning on */
+    cpu_reset(target_cpu_state);
+    target_cpu->powered_off = false;
+    target_cpu_state->halted = 0;
+
+    target_cpu->env.regs[0] = context_id;
+    target_cpu->env.thumb = entry & 1;
+
+    target_cpu_class->set_pc(target_cpu_state, entry);
+}
+
+static void imx6_src_cpu_off(uint32_t cpuid)
+{
+    CPUState *target_cpu_state;
+    ARMCPU *target_cpu;
+
+    DPRINTF("cpu %d\n", cpuid);
+
+    /* change to the cpu we are powering up */
+    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
+    if (!target_cpu_state) {
+        return;
+    }
+    target_cpu = ARM_CPU(target_cpu_state);
+    if (target_cpu->powered_off) {
+        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already off\n",
+                      TYPE_IMX6_SRC, __func__, cpuid);
+        return;
+    }
+
+    target_cpu->powered_off = true;
+    target_cpu_state->halted = 1;
+    target_cpu_state->exception_index = EXCP_HLT;
+    cpu_loop_exit(target_cpu_state);
+}
+
+static void imx6_src_cpu_reset(uint32_t cpuid)
+{
+    CPUState *target_cpu_state;
+    ARMCPU *target_cpu;
+
+    DPRINTF("cpu %d\n", cpuid);
+
+    /* change to the cpu we are powering up */
+    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
+    if (!target_cpu_state) {
+        return;
+    }
+    target_cpu = ARM_CPU(target_cpu_state);
+    if (target_cpu->powered_off) {
+        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is off\n",
+                      TYPE_IMX6_SRC, __func__, cpuid);
+        return;
+    }
+
+    /* Reset the cpu we are turning on */
+    cpu_reset(target_cpu_state);
+}
+
+static uint64_t imx6_src_read(void *opaque, hwaddr offset, unsigned size)
+{
+    uint32 value = 0;
+    IMX6SRCState *s = (IMX6SRCState *)opaque;
+    uint32_t index = offset >> 2;
+
+    if (index < SRC_MAX) {
+        value = s->regs[index];
+    } else {
+        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
+                      HWADDR_PRIx "\n", TYPE_IMX6_SRC, __func__, offset);
+
+    }
+
+    DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx6_src_reg_name(index), value);
+
+    return (uint64_t)value;
+}
+
+static void imx6_src_write(void *opaque, hwaddr offset, uint64_t value,
+                           unsigned size)
+{
+    IMX6SRCState *s = (IMX6SRCState *)opaque;
+    uint32_t index = offset >> 2;
+    uint64_t change_mask;
+
+    if (index >=  SRC_MAX) {
+        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
+                      HWADDR_PRIx "\n", TYPE_IMX6_SRC, __func__, offset);
+        return;
+    }
+
+    DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx6_src_reg_name(index),
+            (uint32_t)value);
+
+    change_mask = s->regs[index] ^ (uint32_t)value;
+
+    switch (index) {
+    case SRC_SCR:
+        if (EXTRACT(change_mask, CORE3_ENABLE)) {
+            if (EXTRACT(value, CORE3_ENABLE)) {
+                /* CORE 3 is brought up */
+                imx6_src_cpu_on(3, s->regs[SRC_GPR7], s->regs[SRC_GPR8]);
+            } else {
+                /* CORE 3 is shut down */
+                imx6_src_cpu_off(3);
+            }
+            /* We clear the reset bits as the processor changed state */
+            clear_bit(CORE3_RST_SHIFT, &value);
+            clear_bit(CORE3_RST_SHIFT, &change_mask);
+        }
+        if (EXTRACT(change_mask, CORE2_ENABLE)) {
+            if (EXTRACT(value, CORE2_ENABLE)) {
+                /* CORE 2 is brought up */
+                imx6_src_cpu_on(2, s->regs[SRC_GPR5], s->regs[SRC_GPR6]);
+            } else {
+                /* CORE 3 is shut down */
+                imx6_src_cpu_off(2);
+            }
+            /* We clear the reset bits as the processor changed state */
+            clear_bit(CORE2_RST_SHIFT, &value);
+            clear_bit(CORE2_RST_SHIFT, &change_mask);
+        }
+        if (EXTRACT(change_mask, CORE1_ENABLE)) {
+            if (EXTRACT(value, CORE1_ENABLE)) {
+                /* CORE 1 is brought up */
+                imx6_src_cpu_on(1, s->regs[SRC_GPR3], s->regs[SRC_GPR4]);
+            } else {
+                /* CORE 3 is shut down */
+                imx6_src_cpu_off(1);
+            }
+            /* We clear the reset bits as the processor changed state */
+            clear_bit(CORE1_RST_SHIFT, &value);
+            clear_bit(CORE1_RST_SHIFT, &change_mask);
+        }
+        if (EXTRACT(change_mask, CORE0_RST)) {
+            imx6_src_cpu_reset(0);
+            clear_bit(CORE0_RST_SHIFT, &value);
+        }
+        if (EXTRACT(change_mask, CORE1_RST)) {
+            imx6_src_cpu_reset(1);
+            clear_bit(CORE1_RST_SHIFT, &value);
+        }
+        if (EXTRACT(change_mask, CORE2_RST)) {
+            imx6_src_cpu_reset(2);
+            clear_bit(CORE2_RST_SHIFT, &value);
+        }
+        if (EXTRACT(change_mask, CORE3_RST)) {
+            imx6_src_cpu_reset(3);
+            clear_bit(CORE3_RST_SHIFT, &value);
+        }
+        if (EXTRACT(change_mask, SW_IPU2_RST)) {
+            /* We pretend the IPU2 is reseted */
+            clear_bit(SW_IPU2_RST_SHIFT, &value);
+        }
+        if (EXTRACT(change_mask, SW_IPU1_RST)) {
+            /* We pretend the IPU1 is reseted */
+            clear_bit(SW_IPU1_RST_SHIFT, &value);
+        }
+        s->regs[index] = value;
+        break;
+    default:
+        s->regs[index] = value;
+        break;
+    }
+}
+
+static const struct MemoryRegionOps imx6_src_ops = {
+    .read = imx6_src_read,
+    .write = imx6_src_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        /*
+         * 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 imx6_src_realize(DeviceState *dev, Error **errp)
+{
+    IMX6SRCState *s = IMX6_SRC(dev);
+
+    memory_region_init_io(&s->iomem, OBJECT(dev), &imx6_src_ops, s,
+                          TYPE_IMX6_SRC, 0x1000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
+}
+
+static void imx6_src_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = imx6_src_realize;
+    dc->reset = imx6_src_reset;
+    dc->vmsd = &vmstate_imx6_src;
+    dc->desc = "i.MX6 System Reset Controller";
+}
+
+static const TypeInfo imx6_src_info = {
+    .name          = TYPE_IMX6_SRC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IMX6SRCState),
+    .class_init    = imx6_src_class_init,
+};
+
+static void imx6_src_register_types(void)
+{
+    type_register_static(&imx6_src_info);
+}
+
+type_init(imx6_src_register_types)
diff --git a/include/hw/misc/imx6_src.h b/include/hw/misc/imx6_src.h
new file mode 100644
index 0000000..c669488
--- /dev/null
+++ b/include/hw/misc/imx6_src.h
@@ -0,0 +1,73 @@
+/*
+ * IMX6 System Reset Controller
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * 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 IMX6_SRC_H
+#define IMX6_SRC_H
+
+#include "hw/sysbus.h"
+#include "qemu/bitops.h"
+
+#define SRC_SCR 0
+#define SRC_SBMR1 1
+#define SRC_SRSR 2
+#define SRC_SISR 5
+#define SRC_SIMR 6
+#define SRC_SBMR2 7
+#define SRC_GPR1 8
+#define SRC_GPR2 9
+#define SRC_GPR3 10
+#define SRC_GPR4 11
+#define SRC_GPR5 12
+#define SRC_GPR6 13
+#define SRC_GPR7 14
+#define SRC_GPR8 15
+#define SRC_GPR9 16
+#define SRC_GPR10 17
+#define SRC_MAX 18
+
+/* SRC_SCR */
+#define CORE3_ENABLE_SHIFT     (24)
+#define CORE3_ENABLE_LENGTH    (1)
+#define CORE2_ENABLE_SHIFT     (23)
+#define CORE2_ENABLE_LENGTH    (1)
+#define CORE1_ENABLE_SHIFT     (22)
+#define CORE1_ENABLE_LENGTH    (1)
+#define CORE3_RST_SHIFT        (16)
+#define CORE3_RST_LENGTH       (1)
+#define CORE2_RST_SHIFT        (15)
+#define CORE2_RST_LENGTH       (1)
+#define CORE1_RST_SHIFT        (14)
+#define CORE1_RST_LENGTH       (1)
+#define CORE0_RST_SHIFT        (13)
+#define CORE0_RST_LENGTH       (1)
+#define SW_IPU1_RST_SHIFT      (3)
+#define SW_IPU1_RST_LENGTH     (1)
+#define SW_IPU2_RST_SHIFT      (12)
+#define SW_IPU2_RST_LENGTH     (1)
+#define WARM_RST_ENABLE_SHIFT  (0)
+#define WARM_RST_ENABLE_LENGTH (1)
+
+#define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH)
+
+#define TYPE_IMX6_SRC "imx6.src"
+#define IMX6_SRC(obj) OBJECT_CHECK(IMX6SRCState, (obj), TYPE_IMX6_SRC)
+
+typedef struct IMX6SRCState {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    MemoryRegion iomem;
+
+    uint32_t regs[SRC_MAX];
+
+} IMX6SRCState;
+
+#endif /* IMX6_SRC_H */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
                   ` (5 preceding siblings ...)
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:31   ` Peter Maydell
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 8/9] i.MX: Add sabrelite i.MX6 emulation Jean-Christophe Dubois
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

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 "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 */
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 8/9] i.MX: Add sabrelite i.MX6 emulation.
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
                   ` (6 preceding siblings ...)
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:25   ` Peter Maydell
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 9/9] i.MX: Add missing descriptions in devices Jean-Christophe Dubois
  2016-02-28 20:27 ` [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe DUBOIS
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

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

Changes since v1:
 * output a message and exit if RAM size is unsupported.

 hw/arm/Makefile.objs |  2 +-
 hw/arm/sabrelite.c   | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/sabrelite.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index ac383df..fc1df45 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -15,4 +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
+obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
new file mode 100644
index 0000000..8db9bbc
--- /dev/null
+++ b/hw/arm/sabrelite.c
@@ -0,0 +1,93 @@
+/*
+ * SABRELITE Board System emulation.
+ *
+ * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
+ *
+ * This code is licensed under the GPL, version 2 or later.
+ * See the file `COPYING' in the top level directory.
+ *
+ * It (partially) emulates a sabrelite board, with a Freescale
+ * i.MX6 SoC
+ */
+
+#include "hw/arm/fsl-imx6.h"
+#include "hw/boards.h"
+#include "qemu/error-report.h"
+#include "exec/address-spaces.h"
+#include "net/net.h"
+#include "hw/devices.h"
+#include "hw/char/serial.h"
+#include "sysemu/qtest.h"
+
+typedef struct IMX6Sabrelite {
+    FslIMX6State soc;
+    MemoryRegion ram;
+} IMX6Sabrelite;
+
+static struct arm_boot_info sabrelite_binfo = {
+    /* DDR memory start */
+    .loader_start = FSL_IMX6_MMDC_ADDR,
+    /* No board ID, we boot from DT tree */
+    .board_id = -1,
+};
+
+/* No need to do any particular setup for secondary boot */
+static void sabrelite_write_secondary(ARMCPU *cpu,
+                                      const struct arm_boot_info *info)
+{
+}
+
+/* Secondary cores are reset through SRC device */
+static void sabrelite_reset_secondary(ARMCPU *cpu,
+                                      const struct arm_boot_info *info)
+{
+}
+
+static void sabrelite_init(MachineState *machine)
+{
+    IMX6Sabrelite *s = g_new0(IMX6Sabrelite, 1);
+    Error *err = NULL;
+
+    object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX6);
+    object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
+                              &error_abort);
+
+    object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
+    if (err != NULL) {
+        error_report("%s", error_get_pretty(err));
+        exit(1);
+    }
+
+    /* Check the amount of memory is compatible with the SOC */
+    if (machine->ram_size > FSL_IMX6_MMDC_SIZE) {
+        error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)\n",
+                     machine->ram_size, FSL_IMX6_MMDC_SIZE);
+        exit(1);
+    }
+
+    memory_region_allocate_system_memory(&s->ram, NULL, "sabrelite.ram",
+                                         machine->ram_size);
+    memory_region_add_subregion(get_system_memory(), FSL_IMX6_MMDC_ADDR,
+                                &s->ram);
+
+    sabrelite_binfo.ram_size = machine->ram_size;
+    sabrelite_binfo.kernel_filename = machine->kernel_filename;
+    sabrelite_binfo.kernel_cmdline = machine->kernel_cmdline;
+    sabrelite_binfo.initrd_filename = machine->initrd_filename;
+    sabrelite_binfo.nb_cpus = smp_cpus;
+    sabrelite_binfo.write_secondary_boot = sabrelite_write_secondary;
+    sabrelite_binfo.secondary_cpu_reset_hook = sabrelite_reset_secondary;
+
+    if (!qtest_enabled()) {
+        arm_load_kernel(&s->soc.cpu[0], &sabrelite_binfo);
+    }
+}
+
+static void sabrelite_machine_init(MachineClass *mc)
+{
+    mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
+    mc->init = sabrelite_init;
+    mc->max_cpus = FSL_IMX6_NUM_CPUS;
+}
+
+DEFINE_MACHINE("sabrelite", sabrelite_machine_init)
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [Qemu-devel] [PATCH v2 9/9] i.MX: Add missing descriptions in devices.
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
                   ` (7 preceding siblings ...)
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 8/9] i.MX: Add sabrelite i.MX6 emulation Jean-Christophe Dubois
@ 2016-02-08 22:08 ` Jean-Christophe Dubois
  2016-02-16 15:21   ` Peter Maydell
  2016-02-28 20:27 ` [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe DUBOIS
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe Dubois @ 2016-02-08 22:08 UTC (permalink / raw)
  To: qemu-devel, peter.maydell, crosthwaite.peter; +Cc: Jean-Christophe Dubois

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

Changes since V1:
 * Not present on V1

 hw/arm/fsl-imx25.c | 1 +
 hw/arm/fsl-imx31.c | 1 +
 hw/i2c/imx_i2c.c   | 1 +
 hw/net/imx_fec.c   | 1 +
 4 files changed, 4 insertions(+)

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index fb743bf..1fbc317 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -291,6 +291,7 @@ static void fsl_imx25_class_init(ObjectClass *oc, void *data)
      * arm_cpu_class_init()
      */
     dc->cannot_destroy_with_object_finalize_yet = true;
+    dc->desc = "i.MX25 SOC";
 }
 
 static const TypeInfo fsl_imx25_type_info = {
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index f2c2ce5..0d69a2c 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -265,6 +265,7 @@ static void fsl_imx31_class_init(ObjectClass *oc, void *data)
      * arm_cpu_class_init()
      */
     dc->cannot_destroy_with_object_finalize_yet = true;
+    dc->desc = "i.MX31 SOC";
 }
 
 static const TypeInfo fsl_imx31_type_info = {
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
index cb62c7a..aa47a63 100644
--- a/hw/i2c/imx_i2c.c
+++ b/hw/i2c/imx_i2c.c
@@ -318,6 +318,7 @@ static void imx_i2c_class_init(ObjectClass *klass, void *data)
     dc->vmsd = &imx_i2c_vmstate;
     dc->reset = imx_i2c_reset;
     dc->realize = imx_i2c_realize;
+    dc->desc = "i.MX I2C controller";
 }
 
 static const TypeInfo imx_i2c_type_info = {
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index c50bf7f..789a0c1 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -692,6 +692,7 @@ static void imx_fec_class_init(ObjectClass *klass, void *data)
     dc->reset = imx_fec_reset;
     dc->props = imx_fec_properties;
     dc->realize = imx_fec_realize;
+    dc->desc = "i.MX FEC Ethernet ccontroller";
 }
 
 static const TypeInfo imx_fec_info = {
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/9] i.MX: Allow GPT timer to rollover.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 1/9] i.MX: Allow GPT timer to rollover Jean-Christophe Dubois
@ 2016-02-16 15:19   ` Peter Maydell
  0 siblings, 0 replies; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:19 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> GPT timer need to rollover when it reaches 0xffffffff.
>
> It also need to reset to 0 when in "restart mode" and crossing the
> compare 1 register.
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/9] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 2/9] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency Jean-Christophe Dubois
@ 2016-02-16 15:20   ` Peter Maydell
  0 siblings, 0 replies; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:20 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> This way all CCM clock defines/enums are named CLK_XXX
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/9] i.MX: Remove CCM useless clock computation handling.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 3/9] i.MX: Remove CCM useless clock computation handling Jean-Christophe Dubois
@ 2016-02-16 15:20   ` Peter Maydell
  0 siblings, 0 replies; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:20 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> Most clocks supported by the CCM are useless to the qemu framework.
>
> Only clocks related to timers (EPIT, GPT, PWM, WATCHDOG, ...) are usefull
> to QEMU code.
>
> Therefore this patch removes clock computation handling for all clocks but:
> * CLK_NONE,
> * CLK_IPG,
> * CLK_32k
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 4/9] i.MX: Add the CLK_IPG_HIGH clock
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 4/9] i.MX: Add the CLK_IPG_HIGH clock Jean-Christophe Dubois
@ 2016-02-16 15:20   ` Peter Maydell
  0 siblings, 0 replies; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:20 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> EPIT, GPT and other i.MX timers are using "abstract" clocks among which
> a CLK_IPG_HIGH clock.
>
> On i.MX25 and i.MX31 CLK_IPG and CLK_IPG_HIGH are mapped to the same clock
> but on other SOC like i.MX6 they are mapped to distinct clocks.
>
> This patch add the CLK_IPG_HIGH to prepare for SOC where these 2 clocks are
> different.
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device Jean-Christophe Dubois
@ 2016-02-16 15:21   ` Peter Maydell
  2016-02-29 17:33   ` Peter Maydell
  1 sibling, 0 replies; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:21 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since V1:
>  * move clk computation to uint64_t to avoid overflow
>  * added explanation on _SET, _CLR and _TOG registers
>  * move CCM and ANALOG handling in sub memory regions.
>
>  hw/misc/Makefile.objs      |   1 +
>  hw/misc/imx6_ccm.c         | 773 +++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/misc/imx6_ccm.h | 197 ++++++++++++
>  3 files changed, 971 insertions(+)
>  create mode 100644 hw/misc/imx6_ccm.c
>  create mode 100644 include/hw/misc/imx6_ccm.h


Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 9/9] i.MX: Add missing descriptions in devices.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 9/9] i.MX: Add missing descriptions in devices Jean-Christophe Dubois
@ 2016-02-16 15:21   ` Peter Maydell
  0 siblings, 0 replies; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:21 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since V1:
>  * Not present on V1
>
>  hw/arm/fsl-imx25.c | 1 +
>  hw/arm/fsl-imx31.c | 1 +
>  hw/i2c/imx_i2c.c   | 1 +
>  hw/net/imx_fec.c   | 1 +
>  4 files changed, 4 insertions(+)
>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 8/9] i.MX: Add sabrelite i.MX6 emulation.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 8/9] i.MX: Add sabrelite i.MX6 emulation Jean-Christophe Dubois
@ 2016-02-16 15:25   ` Peter Maydell
  0 siblings, 0 replies; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:25 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---
>
> Changes since v1:
>  * output a message and exit if RAM size is unsupported.
>
>  hw/arm/Makefile.objs |  2 +-
>  hw/arm/sabrelite.c   | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 94 insertions(+), 1 deletion(-)
>  create mode 100644 hw/arm/sabrelite.c
>
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index ac383df..fc1df45 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -15,4 +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
> +obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
> diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
> new file mode 100644
> index 0000000..8db9bbc
> --- /dev/null
> +++ b/hw/arm/sabrelite.c
> @@ -0,0 +1,93 @@
> +/*
> + * SABRELITE Board System emulation.
> + *
> + * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
> + *
> + * This code is licensed under the GPL, version 2 or later.
> + * See the file `COPYING' in the top level directory.
> + *
> + * It (partially) emulates a sabrelite board, with a Freescale
> + * i.MX6 SoC
> + */
> +
> +#include "hw/arm/fsl-imx6.h"

You need to include "qemu/osdep.h" as the first #include in any
source file. (I forgot to mention this for the earlier patches;
please make sure you fix any other new source files in this patchset).

[This is a new convention we're trying to bring in, so at the moment
things will still compile without it, but if you can add the include
that will save me coming along later with a fixup patch. And at
some point qemu-common.h won't include osdep.h and files will no
longer compile without it explicitly included first...]

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation Jean-Christophe Dubois
@ 2016-02-16 15:31   ` Peter Maydell
  2016-02-16 20:49     ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:31 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device Jean-Christophe Dubois
@ 2016-02-16 15:35   ` Peter Maydell
  2016-02-27 16:57     ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 15:35 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> This controller is also present in i.MX5X devices but they are not
> yet emulated by QEMU.
>
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>

> @@ -0,0 +1,353 @@
> +/*
> + * IMX6 System Reset Controller
> + *
> + * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
> + *
> + * 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 "hw/misc/imx6_src.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/bitops.h"

#include "qemu/osdep.h" as first #include line.

> +static void imx6_src_reset(DeviceState *dev)
> +{
> +    IMX6SRCState *s = IMX6_SRC(dev);
> +
> +    DPRINTF("\n");
> +
> +    /*
> +     * We only clear the first registers as all GPR registers are preserved
> +     * over resets
> +     */
> +    memset(s->regs, 0, SRC_MAX * sizeof(uint32_t));

Comment doesn't seem to match code?

> +    /* Set reset values */
> +    s->regs[SRC_SCR] = 0x521;
> +    s->regs[SRC_SRSR] = 0x1;
> +    s->regs[SRC_SIMR] = 0x1F;
> +}
> +
> +static CPUState *imx6_src_get_cpu_by_id(uint32_t id)
> +{
> +    CPUState *cpu;
> +
> +    DPRINTF("cpu %d\n", id);
> +
> +    CPU_FOREACH(cpu) {
> +        ARMCPU *armcpu = ARM_CPU(cpu);
> +
> +        if (armcpu->mp_affinity == id) {
> +            return cpu;
> +        }
> +    }
> +
> +    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Resquesting unknown CPU %d\n",
> +                  TYPE_IMX6_SRC, __func__, id);
> +
> +    return NULL;
> +}
> +
> +static void imx6_src_cpu_on(uint32_t cpuid, uint32_t entry, uint32_t context_id)
> +{
> +    CPUState *target_cpu_state;
> +    ARMCPU *target_cpu;
> +    CPUClass *target_cpu_class;
> +
> +    DPRINTF("cpu %d @ 0x%08x with R0 = 0x%08x\n", cpuid, entry, context_id);
> +
> +    /* change to the cpu we are powering up */
> +    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
> +    if (!target_cpu_state) {
> +        return;
> +    }
> +    target_cpu = ARM_CPU(target_cpu_state);
> +    if (!target_cpu->powered_off) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already running\n",
> +                      TYPE_IMX6_SRC, __func__, cpuid);
> +        return;
> +    }
> +    target_cpu_class = CPU_GET_CLASS(target_cpu);
> +
> +    /* Initialize the cpu we are turning on */
> +    cpu_reset(target_cpu_state);
> +    target_cpu->powered_off = false;
> +    target_cpu_state->halted = 0;
> +
> +    target_cpu->env.regs[0] = context_id;
> +    target_cpu->env.thumb = entry & 1;
> +
> +    target_cpu_class->set_pc(target_cpu_state, entry);
> +}
> +
> +static void imx6_src_cpu_off(uint32_t cpuid)
> +{
> +    CPUState *target_cpu_state;
> +    ARMCPU *target_cpu;
> +
> +    DPRINTF("cpu %d\n", cpuid);
> +
> +    /* change to the cpu we are powering up */
> +    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
> +    if (!target_cpu_state) {
> +        return;
> +    }
> +    target_cpu = ARM_CPU(target_cpu_state);
> +    if (target_cpu->powered_off) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already off\n",
> +                      TYPE_IMX6_SRC, __func__, cpuid);
> +        return;
> +    }
> +
> +    target_cpu->powered_off = true;
> +    target_cpu_state->halted = 1;
> +    target_cpu_state->exception_index = EXCP_HLT;
> +    cpu_loop_exit(target_cpu_state);
> +}
>
> +static void imx6_src_cpu_reset(uint32_t cpuid)
> +{
> +    CPUState *target_cpu_state;
> +    ARMCPU *target_cpu;
> +
> +    DPRINTF("cpu %d\n", cpuid);
> +
> +    /* change to the cpu we are powering up */
> +    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
> +    if (!target_cpu_state) {
> +        return;
> +    }
> +    target_cpu = ARM_CPU(target_cpu_state);
> +    if (target_cpu->powered_off) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is off\n",
> +                      TYPE_IMX6_SRC, __func__, cpuid);
> +        return;
> +    }
> +
> +    /* Reset the cpu we are turning on */
> +    cpu_reset(target_cpu_state);
> +}

The code that is messing about with target CPUs to power them up
and down needs to be abstracted out into a public API in target-arm/,
so it can be used both by your device and by target-arm/psci.c.
I don't want variations on this code to duplicate into various
devices, because chances are good it will need to change for
multithreaded TCG.

> +static void imx6_src_realize(DeviceState *dev, Error **errp)
> +{
> +    IMX6SRCState *s = IMX6_SRC(dev);
> +
> +    memory_region_init_io(&s->iomem, OBJECT(dev), &imx6_src_ops, s,
> +                          TYPE_IMX6_SRC, 0x1000);
> +    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
> +}
> +
> +static void imx6_src_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->realize = imx6_src_realize;
> +    dc->reset = imx6_src_reset;
> +    dc->vmsd = &vmstate_imx6_src;
> +    dc->desc = "i.MX6 System Reset Controller";
> +}

> +/* SRC_SCR */
> +#define CORE3_ENABLE_SHIFT     (24)
> +#define CORE3_ENABLE_LENGTH    (1)
> +#define CORE2_ENABLE_SHIFT     (23)
> +#define CORE2_ENABLE_LENGTH    (1)
> +#define CORE1_ENABLE_SHIFT     (22)
> +#define CORE1_ENABLE_LENGTH    (1)
> +#define CORE3_RST_SHIFT        (16)
> +#define CORE3_RST_LENGTH       (1)
> +#define CORE2_RST_SHIFT        (15)
> +#define CORE2_RST_LENGTH       (1)
> +#define CORE1_RST_SHIFT        (14)
> +#define CORE1_RST_LENGTH       (1)
> +#define CORE0_RST_SHIFT        (13)
> +#define CORE0_RST_LENGTH       (1)
> +#define SW_IPU1_RST_SHIFT      (3)
> +#define SW_IPU1_RST_LENGTH     (1)
> +#define SW_IPU2_RST_SHIFT      (12)
> +#define SW_IPU2_RST_LENGTH     (1)
> +#define WARM_RST_ENABLE_SHIFT  (0)
> +#define WARM_RST_ENABLE_LENGTH (1)

The brackets here are unnecessary.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-16 15:31   ` Peter Maydell
@ 2016-02-16 20:49     ` Jean-Christophe DUBOIS
  2016-02-16 21:06       ` Peter Maydell
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-16 20:49 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

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
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-16 20:49     ` Jean-Christophe DUBOIS
@ 2016-02-16 21:06       ` Peter Maydell
  2016-02-16 21:47         ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 21:06 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-16 21:06       ` Peter Maydell
@ 2016-02-16 21:47         ` Jean-Christophe DUBOIS
  2016-02-16 21:57           ` Peter Maydell
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-16 21:47 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

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
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-16 21:47         ` Jean-Christophe DUBOIS
@ 2016-02-16 21:57           ` Peter Maydell
  2016-02-18 20:51             ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-16 21:57 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-16 21:57           ` Peter Maydell
@ 2016-02-18 20:51             ` Jean-Christophe DUBOIS
  2016-02-18 21:46               ` Peter Maydell
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-18 20:51 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

[-- Attachment #1: Type: text/plain, Size: 1553 bytes --]

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
>


[-- Attachment #2: Type: text/html, Size: 2629 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-18 20:51             ` Jean-Christophe DUBOIS
@ 2016-02-18 21:46               ` Peter Maydell
  2016-02-19  6:32                 ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-18 21:46 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-18 21:46               ` Peter Maydell
@ 2016-02-19  6:32                 ` Jean-Christophe DUBOIS
  2016-02-19  9:32                   ` Peter Maydell
  2016-02-29 17:58                   ` Peter Maydell
  0 siblings, 2 replies; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-19  6:32 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

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
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-19  6:32                 ` Jean-Christophe DUBOIS
@ 2016-02-19  9:32                   ` Peter Maydell
  2016-02-19 21:06                     ` Jean-Christophe DUBOIS
  2016-02-29 17:58                   ` Peter Maydell
  1 sibling, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-19  9:32 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-19  9:32                   ` Peter Maydell
@ 2016-02-19 21:06                     ` Jean-Christophe DUBOIS
  2016-02-20 10:55                       ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-19 21:06 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]

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
>


[-- Attachment #2: Type: text/html, Size: 2211 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-19 21:06                     ` Jean-Christophe DUBOIS
@ 2016-02-20 10:55                       ` Jean-Christophe DUBOIS
  2016-02-20 15:30                         ` Peter Crosthwaite
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-20 10:55 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

[-- Attachment #1: Type: text/plain, Size: 16952 bytes --]

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
>>
>


[-- Attachment #2: Type: text/html, Size: 22064 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-20 10:55                       ` Jean-Christophe DUBOIS
@ 2016-02-20 15:30                         ` Peter Crosthwaite
  2016-02-20 18:03                           ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Crosthwaite @ 2016-02-20 15:30 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS
  Cc: Rob Herring, Peter Maydell, QEMU Developers, Peter Crosthwaite

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

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-20 15:30                         ` Peter Crosthwaite
@ 2016-02-20 18:03                           ` Jean-Christophe DUBOIS
  2016-02-21  3:42                             ` Peter Crosthwaite
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-20 18:03 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Peter Maydell, QEMU Developers, Peter Crosthwaite

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
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-20 18:03                           ` Jean-Christophe DUBOIS
@ 2016-02-21  3:42                             ` Peter Crosthwaite
  2016-02-21 13:42                               ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Crosthwaite @ 2016-02-21  3:42 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS
  Cc: Rob Herring, Peter Maydell, QEMU Developers, Peter Crosthwaite

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
>>
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-21  3:42                             ` Peter Crosthwaite
@ 2016-02-21 13:42                               ` Jean-Christophe DUBOIS
  0 siblings, 0 replies; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-21 13:42 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Rob Herring, Peter Maydell, QEMU Developers, Peter Crosthwaite

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
>>>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device.
  2016-02-16 15:35   ` Peter Maydell
@ 2016-02-27 16:57     ` Jean-Christophe DUBOIS
  2016-02-27 17:43       ` Peter Maydell
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-27 16:57 UTC (permalink / raw)
  To: Peter Maydell, Peter Crosthwaite; +Cc: QEMU Developers

Hi Peter and Peter,

I need to test that the changes I did for PSCI (factor out on/off code) 
do not introduce any regression.

On which QEMU target should I test my changes to PSCI to check I didn't 
mess up anything?

Thanks

JC

Le 16/02/2016 16:35, Peter Maydell a écrit :
> On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
>> This controller is also present in i.MX5X devices but they are not
>> yet emulated by QEMU.
>>
>> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
>> @@ -0,0 +1,353 @@
>> +/*
>> + * IMX6 System Reset Controller
>> + *
>> + * Copyright (c) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
>> + *
>> + * 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 "hw/misc/imx6_src.h"
>> +#include "sysemu/sysemu.h"
>> +#include "qemu/bitops.h"
> #include "qemu/osdep.h" as first #include line.
>
>> +static void imx6_src_reset(DeviceState *dev)
>> +{
>> +    IMX6SRCState *s = IMX6_SRC(dev);
>> +
>> +    DPRINTF("\n");
>> +
>> +    /*
>> +     * We only clear the first registers as all GPR registers are preserved
>> +     * over resets
>> +     */
>> +    memset(s->regs, 0, SRC_MAX * sizeof(uint32_t));
> Comment doesn't seem to match code?
>
>> +    /* Set reset values */
>> +    s->regs[SRC_SCR] = 0x521;
>> +    s->regs[SRC_SRSR] = 0x1;
>> +    s->regs[SRC_SIMR] = 0x1F;
>> +}
>> +
>> +static CPUState *imx6_src_get_cpu_by_id(uint32_t id)
>> +{
>> +    CPUState *cpu;
>> +
>> +    DPRINTF("cpu %d\n", id);
>> +
>> +    CPU_FOREACH(cpu) {
>> +        ARMCPU *armcpu = ARM_CPU(cpu);
>> +
>> +        if (armcpu->mp_affinity == id) {
>> +            return cpu;
>> +        }
>> +    }
>> +
>> +    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Resquesting unknown CPU %d\n",
>> +                  TYPE_IMX6_SRC, __func__, id);
>> +
>> +    return NULL;
>> +}
>> +
>> +static void imx6_src_cpu_on(uint32_t cpuid, uint32_t entry, uint32_t context_id)
>> +{
>> +    CPUState *target_cpu_state;
>> +    ARMCPU *target_cpu;
>> +    CPUClass *target_cpu_class;
>> +
>> +    DPRINTF("cpu %d @ 0x%08x with R0 = 0x%08x\n", cpuid, entry, context_id);
>> +
>> +    /* change to the cpu we are powering up */
>> +    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
>> +    if (!target_cpu_state) {
>> +        return;
>> +    }
>> +    target_cpu = ARM_CPU(target_cpu_state);
>> +    if (!target_cpu->powered_off) {
>> +        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already running\n",
>> +                      TYPE_IMX6_SRC, __func__, cpuid);
>> +        return;
>> +    }
>> +    target_cpu_class = CPU_GET_CLASS(target_cpu);
>> +
>> +    /* Initialize the cpu we are turning on */
>> +    cpu_reset(target_cpu_state);
>> +    target_cpu->powered_off = false;
>> +    target_cpu_state->halted = 0;
>> +
>> +    target_cpu->env.regs[0] = context_id;
>> +    target_cpu->env.thumb = entry & 1;
>> +
>> +    target_cpu_class->set_pc(target_cpu_state, entry);
>> +}
>> +
>> +static void imx6_src_cpu_off(uint32_t cpuid)
>> +{
>> +    CPUState *target_cpu_state;
>> +    ARMCPU *target_cpu;
>> +
>> +    DPRINTF("cpu %d\n", cpuid);
>> +
>> +    /* change to the cpu we are powering up */
>> +    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
>> +    if (!target_cpu_state) {
>> +        return;
>> +    }
>> +    target_cpu = ARM_CPU(target_cpu_state);
>> +    if (target_cpu->powered_off) {
>> +        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is already off\n",
>> +                      TYPE_IMX6_SRC, __func__, cpuid);
>> +        return;
>> +    }
>> +
>> +    target_cpu->powered_off = true;
>> +    target_cpu_state->halted = 1;
>> +    target_cpu_state->exception_index = EXCP_HLT;
>> +    cpu_loop_exit(target_cpu_state);
>> +}
>>
>> +static void imx6_src_cpu_reset(uint32_t cpuid)
>> +{
>> +    CPUState *target_cpu_state;
>> +    ARMCPU *target_cpu;
>> +
>> +    DPRINTF("cpu %d\n", cpuid);
>> +
>> +    /* change to the cpu we are powering up */
>> +    target_cpu_state = imx6_src_get_cpu_by_id(cpuid);
>> +    if (!target_cpu_state) {
>> +        return;
>> +    }
>> +    target_cpu = ARM_CPU(target_cpu_state);
>> +    if (target_cpu->powered_off) {
>> +        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: CPU %d is off\n",
>> +                      TYPE_IMX6_SRC, __func__, cpuid);
>> +        return;
>> +    }
>> +
>> +    /* Reset the cpu we are turning on */
>> +    cpu_reset(target_cpu_state);
>> +}
> The code that is messing about with target CPUs to power them up
> and down needs to be abstracted out into a public API in target-arm/,
> so it can be used both by your device and by target-arm/psci.c.
> I don't want variations on this code to duplicate into various
> devices, because chances are good it will need to change for
> multithreaded TCG.
>
>> +static void imx6_src_realize(DeviceState *dev, Error **errp)
>> +{
>> +    IMX6SRCState *s = IMX6_SRC(dev);
>> +
>> +    memory_region_init_io(&s->iomem, OBJECT(dev), &imx6_src_ops, s,
>> +                          TYPE_IMX6_SRC, 0x1000);
>> +    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
>> +}
>> +
>> +static void imx6_src_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +    dc->realize = imx6_src_realize;
>> +    dc->reset = imx6_src_reset;
>> +    dc->vmsd = &vmstate_imx6_src;
>> +    dc->desc = "i.MX6 System Reset Controller";
>> +}
>> +/* SRC_SCR */
>> +#define CORE3_ENABLE_SHIFT     (24)
>> +#define CORE3_ENABLE_LENGTH    (1)
>> +#define CORE2_ENABLE_SHIFT     (23)
>> +#define CORE2_ENABLE_LENGTH    (1)
>> +#define CORE1_ENABLE_SHIFT     (22)
>> +#define CORE1_ENABLE_LENGTH    (1)
>> +#define CORE3_RST_SHIFT        (16)
>> +#define CORE3_RST_LENGTH       (1)
>> +#define CORE2_RST_SHIFT        (15)
>> +#define CORE2_RST_LENGTH       (1)
>> +#define CORE1_RST_SHIFT        (14)
>> +#define CORE1_RST_LENGTH       (1)
>> +#define CORE0_RST_SHIFT        (13)
>> +#define CORE0_RST_LENGTH       (1)
>> +#define SW_IPU1_RST_SHIFT      (3)
>> +#define SW_IPU1_RST_LENGTH     (1)
>> +#define SW_IPU2_RST_SHIFT      (12)
>> +#define SW_IPU2_RST_LENGTH     (1)
>> +#define WARM_RST_ENABLE_SHIFT  (0)
>> +#define WARM_RST_ENABLE_LENGTH (1)
> The brackets here are unnecessary.
>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device.
  2016-02-27 16:57     ` Jean-Christophe DUBOIS
@ 2016-02-27 17:43       ` Peter Maydell
  2016-02-28 12:00         ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-27 17:43 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

On 27 February 2016 at 16:57, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> Hi Peter and Peter,
>
> I need to test that the changes I did for PSCI (factor out on/off code) do
> not introduce any regression.
>
> On which QEMU target should I test my changes to PSCI to check I didn't mess
> up anything?

The 'virt' board uses PSCI.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device.
  2016-02-27 17:43       ` Peter Maydell
@ 2016-02-28 12:00         ` Jean-Christophe DUBOIS
  0 siblings, 0 replies; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-28 12:00 UTC (permalink / raw)
  To: Peter Maydell, Peter Crosthwaite; +Cc: QEMU Developers

Le 27/02/2016 18:43, Peter Maydell a écrit :
> On 27 February 2016 at 16:57, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> Hi Peter and Peter,
>>
>> I need to test that the changes I did for PSCI (factor out on/off code) do
>> not introduce any regression.
>>
>> On which QEMU target should I test my changes to PSCI to check I didn't mess
>> up anything?
> The 'virt' board uses PSCI.

Is there some quick howto somewhere on the 'virt' plateform (which linux 
defconfig to use, which DT tree to use, which command line t use, ...) ?

Thanks

JC

>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support
  2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
                   ` (8 preceding siblings ...)
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 9/9] i.MX: Add missing descriptions in devices Jean-Christophe Dubois
@ 2016-02-28 20:27 ` Jean-Christophe DUBOIS
  2016-03-01 19:18   ` Jean-Christophe DUBOIS
  9 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-28 20:27 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, crosthwaite.peter

Peter,

Are you OK if I merge the 2 series (i.MX6 and SPI for i.MX6) into a 
single series?

Thanks.

JC

Le 08/02/2016 23:08, Jean-Christophe Dubois a écrit :
> This patch series adds support for the Freescale i.MX6 processor.
>
> 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
> * 7 GPIO controllers
> * 6 SDHC controllers
> * 1 CCM device
> * 1 SRC device
> * 3 I2C devices
> * various ROM/RAM areas.
>
> This also adds the sabrelite board as a an actual platform for i.MX6.
>
> This series was tested by booting a 4.4 linux kernel (using the
> imx_v6_v7_defconfig file as kernel configuration).
>
> Note1: as sabrelite uses uart2 as console, you have to redirect the second
> QEMU serial port to stdout.
>      qemu-system-arm -M sabrelite -display none ... -serial null -serial stdio
>
> Note2: as the SPI controller is not yet supported in QEMU for i.MX you need
> to disable SPI controllers in Linux DTS tree. Otherwise Linux would hang
> during the boot waiting for a SPI device to respond.
>
> Note3: You need to disable the GPIO section related to physical push buttons
> in the Linux DTS tree in order to avoid excecive interrupt triggering on
> GPIO devices for non existant buttons.
>
> Jean-Christophe Dubois (9):
>    i.MX: Allow GPT timer to rollover.
>    i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency.
>    i.MX: Remove CCM useless clock computation handling.
>    i.MX: Add the CLK_IPG_HIGH clock
>    i.MX: Add i.MX6 CCM and ANALOG device.
>    i.MX: Add i.MX6 System Reset Controller device.
>    i.MX: Add i.MX6 SOC implementation.
>    i.MX: Add sabrelite i.MX6 emulation.
>    i.MX: Add missing descriptions in devices.
>
>   default-configs/arm-softmmu.mak |   1 +
>   hw/arm/Makefile.objs            |   1 +
>   hw/arm/fsl-imx25.c              |   1 +
>   hw/arm/fsl-imx31.c              |   1 +
>   hw/arm/fsl-imx6.c               | 407 +++++++++++++++++++++
>   hw/arm/sabrelite.c              |  93 +++++
>   hw/i2c/imx_i2c.c                |   1 +
>   hw/misc/Makefile.objs           |   2 +
>   hw/misc/imx25_ccm.c             |  29 +-
>   hw/misc/imx31_ccm.c             |  35 +-
>   hw/misc/imx6_ccm.c              | 773 ++++++++++++++++++++++++++++++++++++++++
>   hw/misc/imx6_src.c              | 353 ++++++++++++++++++
>   hw/net/imx_fec.c                |   1 +
>   hw/timer/imx_epit.c             |   8 +-
>   hw/timer/imx_gpt.c              |  43 +--
>   include/hw/arm/fsl-imx6.h       | 447 +++++++++++++++++++++++
>   include/hw/misc/imx6_ccm.h      | 197 ++++++++++
>   include/hw/misc/imx6_src.h      |  73 ++++
>   include/hw/misc/imx_ccm.h       |  10 +-
>   19 files changed, 2384 insertions(+), 92 deletions(-)
>   create mode 100644 hw/arm/fsl-imx6.c
>   create mode 100644 hw/arm/sabrelite.c
>   create mode 100644 hw/misc/imx6_ccm.c
>   create mode 100644 hw/misc/imx6_src.c
>   create mode 100644 include/hw/arm/fsl-imx6.h
>   create mode 100644 include/hw/misc/imx6_ccm.h
>   create mode 100644 include/hw/misc/imx6_src.h
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device.
  2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device Jean-Christophe Dubois
  2016-02-16 15:21   ` Peter Maydell
@ 2016-02-29 17:33   ` Peter Maydell
  2016-02-29 20:15     ` Jean-Christophe DUBOIS
  1 sibling, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-29 17:33 UTC (permalink / raw)
  To: Jean-Christophe Dubois; +Cc: QEMU Developers, Peter Crosthwaite

On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
> ---

> +static uint64_t imx6_ccm_read(void *opaque, hwaddr offset, unsigned size)
> +{
> +    uint32 value = 0;

This should be 'uint32_t', not 'uint32'.

(You'll find this doesn't compile on current master if you rebase it;
uint32 was a type intended only for use with the softfloat code, and
we've just eliminated it.)

Similar issues in imx6_src_read() and imx_spi_read().

You also need to make sure all your new .c files have #include "qemu/osdep.h"
as the first include they do, or they won't build on current master.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-19  6:32                 ` Jean-Christophe DUBOIS
  2016-02-19  9:32                   ` Peter Maydell
@ 2016-02-29 17:58                   ` Peter Maydell
  2016-02-29 20:34                     ` Jean-Christophe DUBOIS
  1 sibling, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-29 17:58 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

On 19 February 2016 at 06:32, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> 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).

I worked out why this happens -- it's because the secondary CPUs and
the primary disagree about whether they're booting in Secure mode.
You can either:
(1) have the board code say "boot the primary in Secure mode":
--- a/hw/arm/sabrelite.c
+++ b/hw/arm/sabrelite.c
@@ -85,6 +85,7 @@ static void sabrelite_init(MachineState *machine)
     sabrelite_binfo.kernel_cmdline = machine->kernel_cmdline;
     sabrelite_binfo.initrd_filename = machine->initrd_filename;
     sabrelite_binfo.nb_cpus = smp_cpus;
+    sabrelite_binfo.secure_boot = true;
     sabrelite_binfo.write_secondary_boot = sabrelite_write_secondary;
     sabrelite_binfo.secondary_cpu_reset_hook = sabrelite_reset_secondary;

or (2) have the code in imx6_src.c tell the secondaries that
they should start in non-secure mode:

--- a/hw/misc/imx6_src.c
+++ b/hw/misc/imx6_src.c
@@ -144,6 +144,7 @@ static void imx6_src_cpu_on(uint32_t cpuid,
uint32_t entry, uint32_t context_id)

     target_cpu->env.regs[0] = context_id;
     target_cpu->env.thumb = entry & 1;
+    target_cpu->env.cp15.scr_el3 |= SCR_NS;

     target_cpu_class->set_pc(target_cpu_state, entry);
 }

If you do either of these then the system will boot the kernel that
you sent the link to.

To answer the question of "which of these is the correct thing to do"
we need to look at what the real hardware does when it's running Linux:
does it run Linux in Secure or Nonsecure?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device.
  2016-02-29 17:33   ` Peter Maydell
@ 2016-02-29 20:15     ` Jean-Christophe DUBOIS
  0 siblings, 0 replies; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-29 20:15 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

Le 29/02/2016 18:33, Peter Maydell a écrit :
> On 8 February 2016 at 22:08, Jean-Christophe Dubois <jcd@tribudubois.net> wrote:
>> Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
>> ---
>> +static uint64_t imx6_ccm_read(void *opaque, hwaddr offset, unsigned size)
>> +{
>> +    uint32 value = 0;
> This should be 'uint32_t', not 'uint32'.
>
> (You'll find this doesn't compile on current master if you rebase it;
> uint32 was a type intended only for use with the softfloat code, and
> we've just eliminated it.)
>
> Similar issues in imx6_src_read() and imx_spi_read().
>
> You also need to make sure all your new .c files have #include "qemu/osdep.h"
> as the first include they do, or they won't build on current master.

OK, I'll do.

>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-29 17:58                   ` Peter Maydell
@ 2016-02-29 20:34                     ` Jean-Christophe DUBOIS
  2016-02-29 21:14                       ` Peter Maydell
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-29 20:34 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

Le 29/02/2016 18:58, Peter Maydell a écrit :
> On 19 February 2016 at 06:32, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> 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).
> I worked out why this happens -- it's because the secondary CPUs and
> the primary disagree about whether they're booting in Secure mode.
> You can either:
> (1) have the board code say "boot the primary in Secure mode":
> --- a/hw/arm/sabrelite.c
> +++ b/hw/arm/sabrelite.c
> @@ -85,6 +85,7 @@ static void sabrelite_init(MachineState *machine)
>       sabrelite_binfo.kernel_cmdline = machine->kernel_cmdline;
>       sabrelite_binfo.initrd_filename = machine->initrd_filename;
>       sabrelite_binfo.nb_cpus = smp_cpus;
> +    sabrelite_binfo.secure_boot = true;
>       sabrelite_binfo.write_secondary_boot = sabrelite_write_secondary;
>       sabrelite_binfo.secondary_cpu_reset_hook = sabrelite_reset_secondary;
>
> or (2) have the code in imx6_src.c tell the secondaries that
> they should start in non-secure mode:
>
> --- a/hw/misc/imx6_src.c
> +++ b/hw/misc/imx6_src.c
> @@ -144,6 +144,7 @@ static void imx6_src_cpu_on(uint32_t cpuid,
> uint32_t entry, uint32_t context_id)
>
>       target_cpu->env.regs[0] = context_id;
>       target_cpu->env.thumb = entry & 1;
> +    target_cpu->env.cp15.scr_el3 |= SCR_NS;
>
>       target_cpu_class->set_pc(target_cpu_state, entry);
>   }
>
> If you do either of these then the system will boot the kernel that
> you sent the link to.

Thanks Peter, It does work.

>
> To answer the question of "which of these is the correct thing to do"
> we need to look at what the real hardware does when it's running Linux:
> does it run Linux in Secure or Nonsecure?

i.MX6 is definitively able to boot in secure/trustzone mode (there are 
some demo out there about it) so I guess it might be booting in secure mode.

>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-29 20:34                     ` Jean-Christophe DUBOIS
@ 2016-02-29 21:14                       ` Peter Maydell
  2016-02-29 21:32                         ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-02-29 21:14 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

On 29 February 2016 at 20:34, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> Le 29/02/2016 18:58, Peter Maydell a écrit :
>> To answer the question of "which of these is the correct thing to do"
>> we need to look at what the real hardware does when it's running Linux:
>> does it run Linux in Secure or Nonsecure?
>
>
> i.MX6 is definitively able to boot in secure/trustzone mode (there are some
> demo out there about it) so I guess it might be booting in secure mode.


Mmm. The other question I had about the system reset controller
is whether it's really purely hardware doing the "start secondary CPU",
or is it just a funny way of asking the system firmware to start
things, or is the stuff like the register for startup address
just a place to leave information that the system firmware
on the secondary CPU will read as part of its boot sequence?

Is there a datasheet available for this?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-29 21:14                       ` Peter Maydell
@ 2016-02-29 21:32                         ` Jean-Christophe DUBOIS
  2016-03-01 16:19                           ` Peter Maydell
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-02-29 21:32 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

Le 29/02/2016 22:14, Peter Maydell a écrit :
> On 29 February 2016 at 20:34, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> Le 29/02/2016 18:58, Peter Maydell a écrit :
>>> To answer the question of "which of these is the correct thing to do"
>>> we need to look at what the real hardware does when it's running Linux:
>>> does it run Linux in Secure or Nonsecure?
>>
>> i.MX6 is definitively able to boot in secure/trustzone mode (there are some
>> demo out there about it) so I guess it might be booting in secure mode.
>
> Mmm. The other question I had about the system reset controller
> is whether it's really purely hardware doing the "start secondary CPU",
> or is it just a funny way of asking the system firmware to start
> things, or is the stuff like the register for startup address
> just a place to leave information that the system firmware
> on the secondary CPU will read as part of its boot sequence?
>
> Is there a datasheet available for this?

Well the SRC device is described in the i.MX6 reference manual.

http://cache.nxp.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf?fpsp=1&WT_TYPE=Reference%20Manuals&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=pdf&WT_ASSET=Documentation&fileExt=.pdf

I believe it is hardware based. Now it might involve some of the 
functions of the internal ROM in the process but we cannot change this 
behavior in any way.

>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-02-29 21:32                         ` Jean-Christophe DUBOIS
@ 2016-03-01 16:19                           ` Peter Maydell
  2016-03-01 19:17                             ` Jean-Christophe DUBOIS
  0 siblings, 1 reply; 47+ messages in thread
From: Peter Maydell @ 2016-03-01 16:19 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

On 29 February 2016 at 21:32, Jean-Christophe DUBOIS
<jcd@tribudubois.net> wrote:
> Le 29/02/2016 22:14, Peter Maydell a écrit :
>> Is there a datasheet available for this?

> Well the SRC device is described in the i.MX6 reference manual.
>
> http://cache.nxp.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf?fpsp=1&WT_TYPE=Reference%20Manuals&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=pdf&WT_ASSET=Documentation&fileExt=.pdf

Thanks for the link.

> I believe it is hardware based. Now it might involve some of the functions
> of the internal ROM in the process but we cannot change this behavior in any
> way.

The datasheet is pretty clear -- registers like the SRC_GPR<n> are just
"holds some state" registers, and when the system reset controller starts
a secondary CPU it runs through some boot ROM code which reads the
GPR controlling the start address and branches to it.

This means the code you have in the SRC emulation is actually implementing
a combination of the SRC hardware and the boot ROM software. That's OK,
but we should have a comment somewhere that makes it clear that that's
what's going on.

(it is possible to implement the "jump to address as per register" as
code that runs in the guest; highbank has a variant on this. It doesn't
really seem necessary here though.)

On the "secure vs nonsecure" question, I'm not completely sure but I
think that the answer is that it will boot in secure. So we should
use the patche that adds "sabrelite_binfo.secure_boot = true;" to the
board code.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.
  2016-03-01 16:19                           ` Peter Maydell
@ 2016-03-01 19:17                             ` Jean-Christophe DUBOIS
  0 siblings, 0 replies; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-03-01 19:17 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Peter Crosthwaite

Le 01/03/2016 17:19, Peter Maydell a écrit :
> On 29 February 2016 at 21:32, Jean-Christophe DUBOIS
> <jcd@tribudubois.net> wrote:
>> Le 29/02/2016 22:14, Peter Maydell a écrit :
>>> Is there a datasheet available for this?
>> Well the SRC device is described in the i.MX6 reference manual.
>>
>> http://cache.nxp.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf?fpsp=1&WT_TYPE=Reference%20Manuals&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=pdf&WT_ASSET=Documentation&fileExt=.pdf
> Thanks for the link.
>
>> I believe it is hardware based. Now it might involve some of the functions
>> of the internal ROM in the process but we cannot change this behavior in any
>> way.
> The datasheet is pretty clear -- registers like the SRC_GPR<n> are just
> "holds some state" registers, and when the system reset controller starts
> a secondary CPU it runs through some boot ROM code which reads the
> GPR controlling the start address and branches to it.
>
> This means the code you have in the SRC emulation is actually implementing
> a combination of the SRC hardware and the boot ROM software. That's OK,
> but we should have a comment somewhere that makes it clear that that's
> what's going on.

OK, I'll add the comment.

JC

>
> (it is possible to implement the "jump to address as per register" as
> code that runs in the guest; highbank has a variant on this. It doesn't
> really seem necessary here though.)
>
> On the "secure vs nonsecure" question, I'm not completely sure but I
> think that the answer is that it will boot in secure. So we should
> use the patche that adds "sabrelite_binfo.secure_boot = true;" to the
> board code.
>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support
  2016-02-28 20:27 ` [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe DUBOIS
@ 2016-03-01 19:18   ` Jean-Christophe DUBOIS
  2016-03-01 19:27     ` Peter Maydell
  0 siblings, 1 reply; 47+ messages in thread
From: Jean-Christophe DUBOIS @ 2016-03-01 19:18 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel, crosthwaite.peter

Peter,

Can I merge the 2 i.MX series as one depend on the other.

Thanks

JC

Le 28/02/2016 21:27, Jean-Christophe DUBOIS a écrit :
> Peter,
>
> Are you OK if I merge the 2 series (i.MX6 and SPI for i.MX6) into a 
> single series?
>
> Thanks.
>
> JC
>
> Le 08/02/2016 23:08, Jean-Christophe Dubois a écrit :
>> This patch series adds support for the Freescale i.MX6 processor.
>>
>> 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
>> * 7 GPIO controllers
>> * 6 SDHC controllers
>> * 1 CCM device
>> * 1 SRC device
>> * 3 I2C devices
>> * various ROM/RAM areas.
>>
>> This also adds the sabrelite board as a an actual platform for i.MX6.
>>
>> This series was tested by booting a 4.4 linux kernel (using the
>> imx_v6_v7_defconfig file as kernel configuration).
>>
>> Note1: as sabrelite uses uart2 as console, you have to redirect the 
>> second
>> QEMU serial port to stdout.
>>      qemu-system-arm -M sabrelite -display none ... -serial null 
>> -serial stdio
>>
>> Note2: as the SPI controller is not yet supported in QEMU for i.MX 
>> you need
>> to disable SPI controllers in Linux DTS tree. Otherwise Linux would hang
>> during the boot waiting for a SPI device to respond.
>>
>> Note3: You need to disable the GPIO section related to physical push 
>> buttons
>> in the Linux DTS tree in order to avoid excecive interrupt triggering on
>> GPIO devices for non existant buttons.
>>
>> Jean-Christophe Dubois (9):
>>    i.MX: Allow GPT timer to rollover.
>>    i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency.
>>    i.MX: Remove CCM useless clock computation handling.
>>    i.MX: Add the CLK_IPG_HIGH clock
>>    i.MX: Add i.MX6 CCM and ANALOG device.
>>    i.MX: Add i.MX6 System Reset Controller device.
>>    i.MX: Add i.MX6 SOC implementation.
>>    i.MX: Add sabrelite i.MX6 emulation.
>>    i.MX: Add missing descriptions in devices.
>>
>>   default-configs/arm-softmmu.mak |   1 +
>>   hw/arm/Makefile.objs            |   1 +
>>   hw/arm/fsl-imx25.c              |   1 +
>>   hw/arm/fsl-imx31.c              |   1 +
>>   hw/arm/fsl-imx6.c               | 407 +++++++++++++++++++++
>>   hw/arm/sabrelite.c              |  93 +++++
>>   hw/i2c/imx_i2c.c                |   1 +
>>   hw/misc/Makefile.objs           |   2 +
>>   hw/misc/imx25_ccm.c             |  29 +-
>>   hw/misc/imx31_ccm.c             |  35 +-
>>   hw/misc/imx6_ccm.c              | 773 
>> ++++++++++++++++++++++++++++++++++++++++
>>   hw/misc/imx6_src.c              | 353 ++++++++++++++++++
>>   hw/net/imx_fec.c                |   1 +
>>   hw/timer/imx_epit.c             |   8 +-
>>   hw/timer/imx_gpt.c              |  43 +--
>>   include/hw/arm/fsl-imx6.h       | 447 +++++++++++++++++++++++
>>   include/hw/misc/imx6_ccm.h      | 197 ++++++++++
>>   include/hw/misc/imx6_src.h      |  73 ++++
>>   include/hw/misc/imx_ccm.h       |  10 +-
>>   19 files changed, 2384 insertions(+), 92 deletions(-)
>>   create mode 100644 hw/arm/fsl-imx6.c
>>   create mode 100644 hw/arm/sabrelite.c
>>   create mode 100644 hw/misc/imx6_ccm.c
>>   create mode 100644 hw/misc/imx6_src.c
>>   create mode 100644 include/hw/arm/fsl-imx6.h
>>   create mode 100644 include/hw/misc/imx6_ccm.h
>>   create mode 100644 include/hw/misc/imx6_src.h
>>
>
>
>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support
  2016-03-01 19:18   ` Jean-Christophe DUBOIS
@ 2016-03-01 19:27     ` Peter Maydell
  0 siblings, 0 replies; 47+ messages in thread
From: Peter Maydell @ 2016-03-01 19:27 UTC (permalink / raw)
  To: Jean-Christophe DUBOIS; +Cc: QEMU Developers, Peter Crosthwaite

On 1 March 2016 at 19:18, Jean-Christophe DUBOIS <jcd@tribudubois.net> wrote:
> Peter,
>
> Can I merge the 2 i.MX series as one depend on the other.

Yes, go ahead.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2016-03-01 19:27 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-08 22:08 [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe Dubois
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 1/9] i.MX: Allow GPT timer to rollover Jean-Christophe Dubois
2016-02-16 15:19   ` Peter Maydell
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 2/9] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency Jean-Christophe Dubois
2016-02-16 15:20   ` Peter Maydell
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 3/9] i.MX: Remove CCM useless clock computation handling Jean-Christophe Dubois
2016-02-16 15:20   ` Peter Maydell
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 4/9] i.MX: Add the CLK_IPG_HIGH clock Jean-Christophe Dubois
2016-02-16 15:20   ` Peter Maydell
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 5/9] i.MX: Add i.MX6 CCM and ANALOG device Jean-Christophe Dubois
2016-02-16 15:21   ` Peter Maydell
2016-02-29 17:33   ` Peter Maydell
2016-02-29 20:15     ` Jean-Christophe DUBOIS
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 6/9] i.MX: Add i.MX6 System Reset Controller device Jean-Christophe Dubois
2016-02-16 15:35   ` Peter Maydell
2016-02-27 16:57     ` Jean-Christophe DUBOIS
2016-02-27 17:43       ` Peter Maydell
2016-02-28 12:00         ` Jean-Christophe DUBOIS
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation Jean-Christophe Dubois
2016-02-16 15:31   ` Peter Maydell
2016-02-16 20:49     ` Jean-Christophe DUBOIS
2016-02-16 21:06       ` Peter Maydell
2016-02-16 21:47         ` Jean-Christophe DUBOIS
2016-02-16 21:57           ` Peter Maydell
2016-02-18 20:51             ` Jean-Christophe DUBOIS
2016-02-18 21:46               ` Peter Maydell
2016-02-19  6:32                 ` Jean-Christophe DUBOIS
2016-02-19  9:32                   ` Peter Maydell
2016-02-19 21:06                     ` Jean-Christophe DUBOIS
2016-02-20 10:55                       ` Jean-Christophe DUBOIS
2016-02-20 15:30                         ` Peter Crosthwaite
2016-02-20 18:03                           ` Jean-Christophe DUBOIS
2016-02-21  3:42                             ` Peter Crosthwaite
2016-02-21 13:42                               ` Jean-Christophe DUBOIS
2016-02-29 17:58                   ` Peter Maydell
2016-02-29 20:34                     ` Jean-Christophe DUBOIS
2016-02-29 21:14                       ` Peter Maydell
2016-02-29 21:32                         ` Jean-Christophe DUBOIS
2016-03-01 16:19                           ` Peter Maydell
2016-03-01 19:17                             ` Jean-Christophe DUBOIS
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 8/9] i.MX: Add sabrelite i.MX6 emulation Jean-Christophe Dubois
2016-02-16 15:25   ` Peter Maydell
2016-02-08 22:08 ` [Qemu-devel] [PATCH v2 9/9] i.MX: Add missing descriptions in devices Jean-Christophe Dubois
2016-02-16 15:21   ` Peter Maydell
2016-02-28 20:27 ` [Qemu-devel] [PATCH v2 0/9] Add i.MX6 (Single/Dual/Quad) support Jean-Christophe DUBOIS
2016-03-01 19:18   ` Jean-Christophe DUBOIS
2016-03-01 19:27     ` Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).