All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2016-03-16 17:18 Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 01/21] loader: Fix incorrect parameter name in load_image_mr() macro Peter Maydell
                   ` (22 more replies)
  0 siblings, 23 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

Here's the target-arm queue; I'm a bit hesitant about the late-landing
various new board/SoC patches, but they won't affect anybody who isn't
trying to use those boards, so I think it's OK.

(There are a few other patches on list which I definitely want to
get in before rc0 but they need a bit more review time I think.)

thanks
-- PMM


The following changes since commit 0ebc03bc065329eaefb6493f5fa7df08df528f2a:

  util/base64.c: Clean includes (2016-03-16 12:48:11 +0000)

are available in the git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20160316

for you to fetch changes up to 10b27d1ab391dbf36f92e1a33179662082401d7a:

  sd: Fix "info qtree" on boards with SD cards (2016-03-16 17:12:46 +0000)

----------------------------------------------------------------
target-arm queue:
 * loader: Fix incorrect parameter name in load_image_mr()
 * Implement MRS (banked) and MSR (banked) instructions
 * virt: Implement versioning for machine model
 * i.MX: some initial patches preparing for i.MX6 support
 * new ASPEED AST2400 SoC and palmetto-bmc machine
 * bcm2835: add some more raspi2 devices
 * sd: fix segfault running "info qtree"

----------------------------------------------------------------
Andrew Baumann (2):
      bcm2835_peripherals: enable sdhci pending-insert quirk for raspberry pi
      bcm2835_aux: add emulation of BCM2835 AUX (aka UART1) block

Andrew Jeffery (4):
      hw/timer: Add ASPEED timer device model
      hw/intc: Add (new) ASPEED VIC device model
      hw/arm: Add ASPEED AST2400 SoC model
      hw/arm: Add palmetto-bmc machine

Grégory ESTRADE (3):
      bcm2835_fb: add framebuffer device for Raspberry Pi
      bcm2835_property: implement framebuffer control/configuration properties
      bcm2835_dma: add emulation of Raspberry Pi DMA controller

Jean-Christophe Dubois (6):
      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 missing descriptions in devices.

Jens Wiklander (1):
      loader: Fix incorrect parameter name in load_image_mr() macro

Peter Maydell (2):
      target-arm: Implement MRS (banked) and MSR (banked) instructions
      sd: Fix "info qtree" on boards with SD cards

Sergey Sorokin (1):
      target-arm: Fix translation level on early translation faults

Wei Huang (2):
      arm: virt: Add an abstract ARM virt machine type
      arm: virt: Move machine class init code to the abstract machine type

 default-configs/arm-softmmu.mak      |   1 +
 hw/arm/Makefile.objs                 |   1 +
 hw/arm/ast2400.c                     | 137 +++++++
 hw/arm/bcm2835_peripherals.c         | 103 ++++-
 hw/arm/bcm2836.c                     |   2 +
 hw/arm/fsl-imx25.c                   |   1 +
 hw/arm/fsl-imx31.c                   |   1 +
 hw/arm/palmetto-bmc.c                |  65 +++
 hw/arm/raspi.c                       |  12 +-
 hw/arm/virt.c                        |  57 ++-
 hw/char/Makefile.objs                |   1 +
 hw/char/bcm2835_aux.c                | 316 ++++++++++++++
 hw/display/Makefile.objs             |   1 +
 hw/display/bcm2835_fb.c              | 424 +++++++++++++++++++
 hw/dma/Makefile.objs                 |   1 +
 hw/dma/bcm2835_dma.c                 | 408 ++++++++++++++++++
 hw/i2c/imx_i2c.c                     |   1 +
 hw/intc/Makefile.objs                |   1 +
 hw/intc/aspeed_vic.c                 | 339 +++++++++++++++
 hw/misc/Makefile.objs                |   1 +
 hw/misc/bcm2835_property.c           | 139 ++++++-
 hw/misc/imx25_ccm.c                  |  29 +-
 hw/misc/imx31_ccm.c                  |  35 +-
 hw/misc/imx6_ccm.c                   | 774 +++++++++++++++++++++++++++++++++++
 hw/net/imx_fec.c                     |   1 +
 hw/sd/sd.c                           |   6 +-
 hw/timer/Makefile.objs               |   1 +
 hw/timer/aspeed_timer.c              | 449 ++++++++++++++++++++
 hw/timer/imx_epit.c                  |   8 +-
 hw/timer/imx_gpt.c                   |  43 +-
 include/hw/arm/ast2400.h             |  35 ++
 include/hw/arm/bcm2835_peripherals.h |   6 +
 include/hw/char/bcm2835_aux.h        |  33 ++
 include/hw/display/bcm2835_fb.h      |  47 +++
 include/hw/dma/bcm2835_dma.h         |  47 +++
 include/hw/intc/aspeed_vic.h         |  48 +++
 include/hw/loader.h                  |   2 +-
 include/hw/misc/bcm2835_property.h   |   5 +-
 include/hw/misc/imx6_ccm.h           | 197 +++++++++
 include/hw/misc/imx_ccm.h            |  10 +-
 include/hw/timer/aspeed_timer.h      |  59 +++
 target-arm/helper.c                  |  22 +-
 target-arm/helper.h                  |   3 +
 target-arm/op_helper.c               | 120 ++++++
 target-arm/translate.c               | 246 ++++++++++-
 trace-events                         |  16 +
 46 files changed, 4114 insertions(+), 140 deletions(-)
 create mode 100644 hw/arm/ast2400.c
 create mode 100644 hw/arm/palmetto-bmc.c
 create mode 100644 hw/char/bcm2835_aux.c
 create mode 100644 hw/display/bcm2835_fb.c
 create mode 100644 hw/dma/bcm2835_dma.c
 create mode 100644 hw/intc/aspeed_vic.c
 create mode 100644 hw/misc/imx6_ccm.c
 create mode 100644 hw/timer/aspeed_timer.c
 create mode 100644 include/hw/arm/ast2400.h
 create mode 100644 include/hw/char/bcm2835_aux.h
 create mode 100644 include/hw/display/bcm2835_fb.h
 create mode 100644 include/hw/dma/bcm2835_dma.h
 create mode 100644 include/hw/intc/aspeed_vic.h
 create mode 100644 include/hw/misc/imx6_ccm.h
 create mode 100644 include/hw/timer/aspeed_timer.h

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

* [Qemu-devel] [PULL 01/21] loader: Fix incorrect parameter name in load_image_mr() macro
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 02/21] target-arm: Implement MRS (banked) and MSR (banked) instructions Peter Maydell
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Jens Wiklander <jens.wiklander@linaro.org>

Fix a typo in the load_image_mr() macro: 'mr' was written when
the parameter name is '_mr'. (This had no visible effects since
the single use of the macro used 'mr' as the argument.)

Fixes 76151cacfe956248a25b38b5e8429465584f47bb "loader: Add
load_image_mr() to load ROM image to a MemoryRegion"

Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/loader.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/loader.h b/include/hw/loader.h
index 0ba7808..b3d1358 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -137,7 +137,7 @@ void hmp_info_roms(Monitor *mon, const QDict *qdict);
 #define rom_add_blob_fixed(_f, _b, _l, _a)      \
     rom_add_blob(_f, _b, _l, _l, _a, NULL, NULL, NULL)
 #define rom_add_file_mr(_f, _mr, _i)            \
-    rom_add_file(_f, NULL, 0, _i, false, mr)
+    rom_add_file(_f, NULL, 0, _i, false, _mr)
 
 #define PC_ROM_MIN_VGA     0xc0000
 #define PC_ROM_MIN_OPTION  0xc8000
-- 
1.9.1

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

* [Qemu-devel] [PULL 02/21] target-arm: Implement MRS (banked) and MSR (banked) instructions
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 01/21] loader: Fix incorrect parameter name in load_image_mr() macro Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 03/21] target-arm: Fix translation level on early translation faults Peter Maydell
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

Starting with the ARMv7 Virtualization Extensions, the A32 and T32
instruction sets provide instructions "MSR (banked)" and "MRS
(banked)" which can be used to access registers for a mode other
than the current one:
 * R<m>_<mode>
 * ELR_hyp
 * SPSR_<mode>

Implement the missing instructions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1456762734-23939-1-git-send-email-peter.maydell@linaro.org
---
 target-arm/helper.h    |   3 +
 target-arm/op_helper.c | 120 ++++++++++++++++++++++++
 target-arm/translate.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 366 insertions(+), 3 deletions(-)

diff --git a/target-arm/helper.h b/target-arm/helper.h
index e3d09d9..84aa637 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -77,6 +77,9 @@ DEF_HELPER_1(exception_return, void, env)
 DEF_HELPER_2(get_r13_banked, i32, env, i32)
 DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
 
+DEF_HELPER_3(mrs_banked, i32, env, i32, i32)
+DEF_HELPER_4(msr_banked, void, env, i32, i32, i32)
+
 DEF_HELPER_2(get_user_reg, i32, env, i32)
 DEF_HELPER_3(set_user_reg, void, env, i32, i32)
 
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 92fde0a..d626ff1 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -494,6 +494,126 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
     }
 }
 
+static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
+                                      uint32_t regno)
+{
+    /* Raise an exception if the requested access is one of the UNPREDICTABLE
+     * cases; otherwise return. This broadly corresponds to the pseudocode
+     * BankedRegisterAccessValid() and SPSRAccessValid(),
+     * except that we have already handled some cases at translate time.
+     */
+    int curmode = env->uncached_cpsr & CPSR_M;
+
+    if (curmode == tgtmode) {
+        goto undef;
+    }
+
+    if (tgtmode == ARM_CPU_MODE_USR) {
+        switch (regno) {
+        case 8 ... 12:
+            if (curmode != ARM_CPU_MODE_FIQ) {
+                goto undef;
+            }
+            break;
+        case 13:
+            if (curmode == ARM_CPU_MODE_SYS) {
+                goto undef;
+            }
+            break;
+        case 14:
+            if (curmode == ARM_CPU_MODE_HYP || curmode == ARM_CPU_MODE_SYS) {
+                goto undef;
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    if (tgtmode == ARM_CPU_MODE_HYP) {
+        switch (regno) {
+        case 17: /* ELR_Hyp */
+            if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
+                goto undef;
+            }
+            break;
+        default:
+            if (curmode != ARM_CPU_MODE_MON) {
+                goto undef;
+            }
+            break;
+        }
+    }
+
+    return;
+
+undef:
+    raise_exception(env, EXCP_UDEF, syn_uncategorized(),
+                    exception_target_el(env));
+}
+
+void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
+                        uint32_t regno)
+{
+    msr_mrs_banked_exc_checks(env, tgtmode, regno);
+
+    switch (regno) {
+    case 16: /* SPSRs */
+        env->banked_spsr[bank_number(tgtmode)] = value;
+        break;
+    case 17: /* ELR_Hyp */
+        env->elr_el[2] = value;
+        break;
+    case 13:
+        env->banked_r13[bank_number(tgtmode)] = value;
+        break;
+    case 14:
+        env->banked_r14[bank_number(tgtmode)] = value;
+        break;
+    case 8 ... 12:
+        switch (tgtmode) {
+        case ARM_CPU_MODE_USR:
+            env->usr_regs[regno - 8] = value;
+            break;
+        case ARM_CPU_MODE_FIQ:
+            env->fiq_regs[regno - 8] = value;
+            break;
+        default:
+            g_assert_not_reached();
+        }
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
+uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
+{
+    msr_mrs_banked_exc_checks(env, tgtmode, regno);
+
+    switch (regno) {
+    case 16: /* SPSRs */
+        return env->banked_spsr[bank_number(tgtmode)];
+    case 17: /* ELR_Hyp */
+        return env->elr_el[2];
+    case 13:
+        return env->banked_r13[bank_number(tgtmode)];
+    case 14:
+        return env->banked_r14[bank_number(tgtmode)];
+    case 8 ... 12:
+        switch (tgtmode) {
+        case ARM_CPU_MODE_USR:
+            return env->usr_regs[regno - 8];
+        case ARM_CPU_MODE_FIQ:
+            return env->fiq_regs[regno - 8];
+        default:
+            g_assert_not_reached();
+        }
+    default:
+        g_assert_not_reached();
+    }
+}
+
 void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
                                  uint32_t isread)
 {
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 025c7a5..2827519 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4160,6 +4160,195 @@ static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val
     return gen_set_psr(s, mask, spsr, tmp);
 }
 
+static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
+                                     int *tgtmode, int *regno)
+{
+    /* Decode the r and sysm fields of MSR/MRS banked accesses into
+     * the target mode and register number, and identify the various
+     * unpredictable cases.
+     * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
+     *  + executed in user mode
+     *  + using R15 as the src/dest register
+     *  + accessing an unimplemented register
+     *  + accessing a register that's inaccessible at current PL/security state*
+     *  + accessing a register that you could access with a different insn
+     * We choose to UNDEF in all these cases.
+     * Since we don't know which of the various AArch32 modes we are in
+     * we have to defer some checks to runtime.
+     * Accesses to Monitor mode registers from Secure EL1 (which implies
+     * that EL3 is AArch64) must trap to EL3.
+     *
+     * If the access checks fail this function will emit code to take
+     * an exception and return false. Otherwise it will return true,
+     * and set *tgtmode and *regno appropriately.
+     */
+    int exc_target = default_exception_el(s);
+
+    /* These instructions are present only in ARMv8, or in ARMv7 with the
+     * Virtualization Extensions.
+     */
+    if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
+        !arm_dc_feature(s, ARM_FEATURE_EL2)) {
+        goto undef;
+    }
+
+    if (IS_USER(s) || rn == 15) {
+        goto undef;
+    }
+
+    /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
+     * of registers into (r, sysm).
+     */
+    if (r) {
+        /* SPSRs for other modes */
+        switch (sysm) {
+        case 0xe: /* SPSR_fiq */
+            *tgtmode = ARM_CPU_MODE_FIQ;
+            break;
+        case 0x10: /* SPSR_irq */
+            *tgtmode = ARM_CPU_MODE_IRQ;
+            break;
+        case 0x12: /* SPSR_svc */
+            *tgtmode = ARM_CPU_MODE_SVC;
+            break;
+        case 0x14: /* SPSR_abt */
+            *tgtmode = ARM_CPU_MODE_ABT;
+            break;
+        case 0x16: /* SPSR_und */
+            *tgtmode = ARM_CPU_MODE_UND;
+            break;
+        case 0x1c: /* SPSR_mon */
+            *tgtmode = ARM_CPU_MODE_MON;
+            break;
+        case 0x1e: /* SPSR_hyp */
+            *tgtmode = ARM_CPU_MODE_HYP;
+            break;
+        default: /* unallocated */
+            goto undef;
+        }
+        /* We arbitrarily assign SPSR a register number of 16. */
+        *regno = 16;
+    } else {
+        /* general purpose registers for other modes */
+        switch (sysm) {
+        case 0x0 ... 0x6:   /* 0b00xxx : r8_usr ... r14_usr */
+            *tgtmode = ARM_CPU_MODE_USR;
+            *regno = sysm + 8;
+            break;
+        case 0x8 ... 0xe:   /* 0b01xxx : r8_fiq ... r14_fiq */
+            *tgtmode = ARM_CPU_MODE_FIQ;
+            *regno = sysm;
+            break;
+        case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
+            *tgtmode = ARM_CPU_MODE_IRQ;
+            *regno = sysm & 1 ? 13 : 14;
+            break;
+        case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
+            *tgtmode = ARM_CPU_MODE_SVC;
+            *regno = sysm & 1 ? 13 : 14;
+            break;
+        case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
+            *tgtmode = ARM_CPU_MODE_ABT;
+            *regno = sysm & 1 ? 13 : 14;
+            break;
+        case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
+            *tgtmode = ARM_CPU_MODE_UND;
+            *regno = sysm & 1 ? 13 : 14;
+            break;
+        case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
+            *tgtmode = ARM_CPU_MODE_MON;
+            *regno = sysm & 1 ? 13 : 14;
+            break;
+        case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
+            *tgtmode = ARM_CPU_MODE_HYP;
+            /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
+            *regno = sysm & 1 ? 13 : 17;
+            break;
+        default: /* unallocated */
+            goto undef;
+        }
+    }
+
+    /* Catch the 'accessing inaccessible register' cases we can detect
+     * at translate time.
+     */
+    switch (*tgtmode) {
+    case ARM_CPU_MODE_MON:
+        if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
+            goto undef;
+        }
+        if (s->current_el == 1) {
+            /* If we're in Secure EL1 (which implies that EL3 is AArch64)
+             * then accesses to Mon registers trap to EL3
+             */
+            exc_target = 3;
+            goto undef;
+        }
+        break;
+    case ARM_CPU_MODE_HYP:
+        /* Note that we can forbid accesses from EL2 here because they
+         * must be from Hyp mode itself
+         */
+        if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
+            goto undef;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return true;
+
+undef:
+    /* If we get here then some access check did not pass */
+    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
+    return false;
+}
+
+static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
+{
+    TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
+    int tgtmode, regno;
+
+    if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
+        return;
+    }
+
+    /* Sync state because msr_banked() can raise exceptions */
+    gen_set_condexec(s);
+    gen_set_pc_im(s, s->pc - 4);
+    tcg_reg = load_reg(s, rn);
+    tcg_tgtmode = tcg_const_i32(tgtmode);
+    tcg_regno = tcg_const_i32(regno);
+    gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
+    tcg_temp_free_i32(tcg_tgtmode);
+    tcg_temp_free_i32(tcg_regno);
+    tcg_temp_free_i32(tcg_reg);
+    s->is_jmp = DISAS_UPDATE;
+}
+
+static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
+{
+    TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
+    int tgtmode, regno;
+
+    if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
+        return;
+    }
+
+    /* Sync state because mrs_banked() can raise exceptions */
+    gen_set_condexec(s);
+    gen_set_pc_im(s, s->pc - 4);
+    tcg_reg = tcg_temp_new_i32();
+    tcg_tgtmode = tcg_const_i32(tgtmode);
+    tcg_regno = tcg_const_i32(regno);
+    gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
+    tcg_temp_free_i32(tcg_tgtmode);
+    tcg_temp_free_i32(tcg_regno);
+    store_reg(s, rn, tcg_reg);
+    s->is_jmp = DISAS_UPDATE;
+}
+
 /* Generate an old-style exception return. Marks pc as dead. */
 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
 {
@@ -8022,7 +8211,26 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
         sh = (insn >> 4) & 0xf;
         rm = insn & 0xf;
         switch (sh) {
-        case 0x0: /* move program status register */
+        case 0x0: /* MSR, MRS */
+            if (insn & (1 << 9)) {
+                /* MSR (banked) and MRS (banked) */
+                int sysm = extract32(insn, 16, 4) |
+                    (extract32(insn, 8, 1) << 4);
+                int r = extract32(insn, 22, 1);
+
+                if (op1 & 1) {
+                    /* MSR (banked) */
+                    gen_msr_banked(s, r, sysm, rm);
+                } else {
+                    /* MRS (banked) */
+                    int rd = extract32(insn, 12, 4);
+
+                    gen_mrs_banked(s, r, sysm, rd);
+                }
+                break;
+            }
+
+            /* MSR, MRS (for PSRs) */
             if (op1 & 1) {
                 /* PSR = reg */
                 tmp = load_reg(s, rm);
@@ -10133,6 +10341,18 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                         if (arm_dc_feature(s, ARM_FEATURE_M)) {
                             goto illegal_op;
                         }
+
+                        if (extract32(insn, 5, 1)) {
+                            /* MSR (banked) */
+                            int sysm = extract32(insn, 8, 4) |
+                                (extract32(insn, 4, 1) << 4);
+                            int r = op & 1;
+
+                            gen_msr_banked(s, r, sysm, rm);
+                            break;
+                        }
+
+                        /* MSR (for PSRs) */
                         tmp = load_reg(s, rn);
                         if (gen_set_psr(s,
                               msr_mask(s, (insn >> 8) & 0xf, op == 1),
@@ -10205,7 +10425,17 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                         tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
                         gen_exception_return(s, tmp);
                         break;
-                    case 6: /* mrs cpsr.  */
+                    case 6: /* MRS */
+                        if (extract32(insn, 5, 1)) {
+                            /* MRS (banked) */
+                            int sysm = extract32(insn, 16, 4) |
+                                (extract32(insn, 4, 1) << 4);
+
+                            gen_mrs_banked(s, 0, sysm, rd);
+                            break;
+                        }
+
+                        /* mrs cpsr */
                         tmp = tcg_temp_new_i32();
                         if (arm_dc_feature(s, ARM_FEATURE_M)) {
                             addr = tcg_const_i32(insn & 0xff);
@@ -10216,7 +10446,17 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                         }
                         store_reg(s, rd, tmp);
                         break;
-                    case 7: /* mrs spsr.  */
+                    case 7: /* MRS */
+                        if (extract32(insn, 5, 1)) {
+                            /* MRS (banked) */
+                            int sysm = extract32(insn, 16, 4) |
+                                (extract32(insn, 4, 1) << 4);
+
+                            gen_mrs_banked(s, 1, sysm, rd);
+                            break;
+                        }
+
+                        /* mrs spsr.  */
                         /* Not accessible in user mode.  */
                         if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
                             goto illegal_op;
-- 
1.9.1

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

* [Qemu-devel] [PULL 03/21] target-arm: Fix translation level on early translation faults
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 01/21] loader: Fix incorrect parameter name in load_image_mr() macro Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 02/21] target-arm: Implement MRS (banked) and MSR (banked) instructions Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 04/21] arm: virt: Add an abstract ARM virt machine type Peter Maydell
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Sergey Sorokin <afarallax@yandex.ru>

Qemu reports translation fault on 1st level instead of 0th level in case of
AArch64 address translation if the translation table walk is disabled or
the address is in the gap between the two regions.

Signed-off-by: Sergey Sorokin <afarallax@yandex.ru>
Message-id: 1457527503-25958-1-git-send-email-afarallax@yandex.ru
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/helper.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index eaded41..19d5d52 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -7237,7 +7237,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     CPUState *cs = CPU(cpu);
     /* Read an LPAE long-descriptor translation table. */
     MMUFaultType fault_type = translation_fault;
-    uint32_t level = 1;
+    uint32_t level;
     uint32_t epd = 0;
     int32_t t0sz, t1sz;
     uint32_t tg;
@@ -7248,7 +7248,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
     target_ulong page_size;
     uint32_t attrs;
     int32_t stride = 9;
-    int32_t va_size = 32;
+    int32_t va_size;
     int inputsize;
     int32_t tbi = 0;
     TCR *tcr = regime_tcr(env, mmu_idx);
@@ -7264,6 +7264,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
      * support for those page table walks.
      */
     if (arm_el_is_aa64(env, el)) {
+        level = 0;
         va_size = 64;
         if (el > 1) {
             if (mmu_idx != ARMMMUIdx_S2NS) {
@@ -7285,6 +7286,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
             ttbr1_valid = false;
         }
     } else {
+        level = 1;
+        va_size = 32;
         /* There is no TTBR1 for EL2 */
         if (el == 2) {
             ttbr1_valid = false;
@@ -7407,27 +7410,26 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
         /* For stage 2 translations the starting level is specified by the
          * VTCR_EL2.SL0 field (whose interpretation depends on the page size)
          */
-        int startlevel = extract32(tcr->raw_tcr, 6, 2);
+        uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
+        uint32_t startlevel;
         bool ok;
 
         if (va_size == 32 || stride == 9) {
             /* AArch32 or 4KB pages */
-            level = 2 - startlevel;
+            startlevel = 2 - sl0;
         } else {
             /* 16KB or 64KB pages */
-            level = 3 - startlevel;
+            startlevel = 3 - sl0;
         }
 
         /* Check that the starting level is valid. */
-        ok = check_s2_mmu_setup(cpu, va_size == 64, level, inputsize, stride);
+        ok = check_s2_mmu_setup(cpu, va_size == 64, startlevel,
+                                inputsize, stride);
         if (!ok) {
-            /* AArch64 reports these as level 0 faults.
-             * AArch32 reports these as level 1 faults.
-             */
-            level = va_size == 64 ? 0 : 1;
             fault_type = translation_fault;
             goto do_fault;
         }
+        level = startlevel;
     }
 
     /* Clear the vaddr bits which aren't part of the within-region address,
-- 
1.9.1

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

* [Qemu-devel] [PULL 04/21] arm: virt: Add an abstract ARM virt machine type
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (2 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 03/21] target-arm: Fix translation level on early translation faults Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 05/21] arm: virt: Move machine class init code to the abstract " Peter Maydell
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Wei Huang <wei@redhat.com>

In preparation for future ARM virt machine types, this patch creates
an abstract type for all ARM machines. The current machine type in
QEMU (i.e. "virt") is renamed to "virt-2.6", whose naming scheme is
similar to other architectures. For the purpose of backward compatibility,
"virt" is converted to an alias, pointing to "virt-2.6". With this patch,
"qemu -M ?" lists the following virtual machine types along with others:

virt                 QEMU 2.6 ARM Virtual Machine (alias of virt-2.6)
virt-2.6             QEMU 2.6 ARM Virtual Machine

Signed-off-by: Wei Huang <wei@redhat.com>
Message-id: 1457717778-17727-2-git-send-email-wei@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8c6c996..be9bbfb 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1345,6 +1345,19 @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
     }
 }
 
+static void virt_machine_class_init(ObjectClass *oc, void *data)
+{
+}
+
+static const TypeInfo virt_machine_info = {
+    .name          = TYPE_VIRT_MACHINE,
+    .parent        = TYPE_MACHINE,
+    .abstract      = true,
+    .instance_size = sizeof(VirtMachineState),
+    .class_size    = sizeof(VirtMachineClass),
+    .class_init    = virt_machine_class_init,
+};
+
 static void virt_instance_init(Object *obj)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -1382,7 +1395,8 @@ static void virt_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
 
-    mc->desc = "ARM Virtual Machine",
+    mc->desc = "QEMU 2.6 ARM Virtual Machine";
+    mc->alias = "virt";
     mc->init = machvirt_init;
     /* Start max_cpus at the maximum QEMU supports. We'll further restrict
      * it later in machvirt_init, where we have more information about the
@@ -1396,16 +1410,15 @@ static void virt_class_init(ObjectClass *oc, void *data)
 }
 
 static const TypeInfo machvirt_info = {
-    .name = TYPE_VIRT_MACHINE,
-    .parent = TYPE_MACHINE,
-    .instance_size = sizeof(VirtMachineState),
+    .name = MACHINE_TYPE_NAME("virt-2.6"),
+    .parent = TYPE_VIRT_MACHINE,
     .instance_init = virt_instance_init,
-    .class_size = sizeof(VirtMachineClass),
     .class_init = virt_class_init,
 };
 
 static void machvirt_machine_init(void)
 {
+    type_register_static(&virt_machine_info);
     type_register_static(&machvirt_info);
 }
 
-- 
1.9.1

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

* [Qemu-devel] [PULL 05/21] arm: virt: Move machine class init code to the abstract machine type
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (3 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 04/21] arm: virt: Add an abstract ARM virt machine type Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 06/21] i.MX: Allow GPT timer to rollover Peter Maydell
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Wei Huang <wei@redhat.com>

This patch moves the common class initialization code from
"virt-2.6" to the new abstract class. An empty property is added to
"virt-2.6" machine. In the meanwhile, related funtions are renamed
to "virt_2_6_*" for consistency.

Signed-off-by: Wei Huang <wei@redhat.com>
Message-id: 1457717778-17727-3-git-send-email-wei@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index be9bbfb..8c3ac0d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1347,6 +1347,18 @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
 
 static void virt_machine_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->init = machvirt_init;
+    /* Start max_cpus at the maximum QEMU supports. We'll further restrict
+     * it later in machvirt_init, where we have more information about the
+     * configuration of the particular instance.
+     */
+    mc->max_cpus = MAX_CPUMASK_BITS;
+    mc->has_dynamic_sysbus = true;
+    mc->block_default_type = IF_VIRTIO;
+    mc->no_cdrom = 1;
+    mc->pci_allow_0_address = true;
 }
 
 static const TypeInfo virt_machine_info = {
@@ -1358,7 +1370,7 @@ static const TypeInfo virt_machine_info = {
     .class_init    = virt_machine_class_init,
 };
 
-static void virt_instance_init(Object *obj)
+static void virt_2_6_instance_init(Object *obj)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
 
@@ -1391,29 +1403,23 @@ static void virt_instance_init(Object *obj)
                                     "Valid values are 2, 3 and host", NULL);
 }
 
-static void virt_class_init(ObjectClass *oc, void *data)
+static void virt_2_6_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
+        { /* end of list */ }
+    };
 
     mc->desc = "QEMU 2.6 ARM Virtual Machine";
     mc->alias = "virt";
-    mc->init = machvirt_init;
-    /* Start max_cpus at the maximum QEMU supports. We'll further restrict
-     * it later in machvirt_init, where we have more information about the
-     * configuration of the particular instance.
-     */
-    mc->max_cpus = MAX_CPUMASK_BITS;
-    mc->has_dynamic_sysbus = true;
-    mc->block_default_type = IF_VIRTIO;
-    mc->no_cdrom = 1;
-    mc->pci_allow_0_address = true;
+    mc->compat_props = compat_props;
 }
 
 static const TypeInfo machvirt_info = {
     .name = MACHINE_TYPE_NAME("virt-2.6"),
     .parent = TYPE_VIRT_MACHINE,
-    .instance_init = virt_instance_init,
-    .class_init = virt_class_init,
+    .instance_init = virt_2_6_instance_init,
+    .class_init = virt_2_6_class_init,
 };
 
 static void machvirt_machine_init(void)
-- 
1.9.1

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

* [Qemu-devel] [PULL 06/21] i.MX: Allow GPT timer to rollover.
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (4 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 05/21] arm: virt: Move machine class init code to the abstract " Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 07/21] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency Peter Maydell
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Jean-Christophe Dubois <jcd@tribudubois.net>

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.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Message-id: 6e2b36117a249a78bf822dd59a390368f407136e.1456868959.git.jcd@tribudubois.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 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 5cdc3b3..916577b 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -134,7 +134,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)) {
@@ -142,20 +142,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 */
-- 
1.9.1

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

* [Qemu-devel] [PULL 07/21] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency.
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (5 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 06/21] i.MX: Allow GPT timer to rollover Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 08/21] i.MX: Remove CCM useless clock computation handling Peter Maydell
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Jean-Christophe Dubois <jcd@tribudubois.net>

This way all CCM clock defines/enums are named CLK_XXX

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Message-id: 8537df765c1713625c7a8b9aca4c7ca60b42e0c0.1456868959.git.jcd@tribudubois.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 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 498e84c..7a29c19 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -182,7 +182,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 17640bf..7a8fcd2 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -209,7 +209,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 38fbf27..9f26ba8 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -52,7 +52,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 916577b..40db63c 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -81,14 +81,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,
-- 
1.9.1

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

* [Qemu-devel] [PULL 08/21] i.MX: Remove CCM useless clock computation handling.
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (6 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 07/21] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 09/21] i.MX: Add the CLK_IPG_HIGH clock Peter Maydell
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Jean-Christophe Dubois <jcd@tribudubois.net>

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

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Message-id: 9e7222efb349801032e60c0f6b0fbad0e5dcf648.1456868959.git.jcd@tribudubois.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 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 7a29c19..e138fc6 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -120,20 +120,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;
@@ -184,18 +170,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 7a8fcd2..a5caabb 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -152,32 +152,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;
@@ -211,12 +185,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;
 
-- 
1.9.1

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

* [Qemu-devel] [PULL 09/21] i.MX: Add the CLK_IPG_HIGH clock
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (7 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 08/21] i.MX: Remove CCM useless clock computation handling Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 10/21] i.MX: Add i.MX6 CCM and ANALOG device Peter Maydell
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Jean-Christophe Dubois <jcd@tribudubois.net>

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.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Message-id: 224bf650194760284cb40630e985867e1373276a.1456868959.git.jcd@tribudubois.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 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 e138fc6..225604d 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -171,6 +171,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 a5caabb..80c1647 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -186,6 +186,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 9f26ba8..f5836e2 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -52,10 +52,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 40db63c..ab2e213 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -81,14 +81,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;
 
-- 
1.9.1

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

* [Qemu-devel] [PULL 10/21] i.MX: Add i.MX6 CCM and ANALOG device.
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (8 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 09/21] i.MX: Add the CLK_IPG_HIGH clock Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 11/21] i.MX: Add missing descriptions in devices Peter Maydell
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Jean-Christophe Dubois <jcd@tribudubois.net>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Message-id: 9fa80b4d8c5d0f50c94e77d74f952a7a665e168f.1456868959.git.jcd@tribudubois.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/Makefile.objs      |   1 +
 hw/misc/imx6_ccm.c         | 774 +++++++++++++++++++++++++++++++++++++++++++++
 include/hw/misc/imx6_ccm.h | 197 ++++++++++++
 3 files changed, 972 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 ea6cd3c..44ac2e1 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..4e1d49d
--- /dev/null
+++ b/hw/misc/imx6_ccm.c
@@ -0,0 +1,774 @@
+/*
+ * 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 "qemu/osdep.h"
+#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_t 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 */
-- 
1.9.1

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

* [Qemu-devel] [PULL 11/21] i.MX: Add missing descriptions in devices.
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (9 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 10/21] i.MX: Add i.MX6 CCM and ANALOG device Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 12/21] hw/timer: Add ASPEED timer device model Peter Maydell
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Jean-Christophe Dubois <jcd@tribudubois.net>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
Message-id: f1f565eb9dffdeb582feb1b15ba9e8b0afcf5468.1456868959.git.jcd@tribudubois.net
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 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 e435448..a01e43e 100644
--- a/hw/i2c/imx_i2c.c
+++ b/hw/i2c/imx_i2c.c
@@ -319,6 +319,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 3bd5517..e60e338 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -693,6 +693,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 Controller";
 }
 
 static const TypeInfo imx_fec_info = {
-- 
1.9.1

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

* [Qemu-devel] [PULL 12/21] hw/timer: Add ASPEED timer device model
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (10 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 11/21] i.MX: Add missing descriptions in devices Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 13/21] hw/intc: Add (new) ASPEED VIC " Peter Maydell
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Jeffery <andrew@aj.id.au>

Implement basic ASPEED timer functionality for the AST2400 SoC[1]: Up to
8 timers can independently be configured, enabled, reset and disabled.
Some hardware features are not implemented, namely clock value matching
and pulse generation, but the implementation is enough to boot the Linux
kernel configured with aspeed_defconfig.

[1] http://www.aspeedtech.com/products.php?fPath=20&rId=376

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1458096317-25223-2-git-send-email-andrew@aj.id.au
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 default-configs/arm-softmmu.mak |   1 +
 hw/timer/Makefile.objs          |   1 +
 hw/timer/aspeed_timer.c         | 449 ++++++++++++++++++++++++++++++++++++++++
 include/hw/timer/aspeed_timer.h |  59 ++++++
 trace-events                    |   9 +
 5 files changed, 519 insertions(+)
 create mode 100644 hw/timer/aspeed_timer.c
 create mode 100644 include/hw/timer/aspeed_timer.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a9f82a1..2bcd236 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -110,3 +110,4 @@ CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_ACPI=y
 CONFIG_SMBIOS=y
+CONFIG_ASPEED_SOC=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 5cfea6e..003c14f 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -32,3 +32,4 @@ obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
 
 common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
+common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
new file mode 100644
index 0000000..51e8303
--- /dev/null
+++ b/hw/timer/aspeed_timer.c
@@ -0,0 +1,449 @@
+/*
+ * ASPEED AST2400 Timer
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ *
+ * Copyright (C) 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/ptimer.h"
+#include "hw/sysbus.h"
+#include "hw/timer/aspeed_timer.h"
+#include "qemu-common.h"
+#include "qemu/bitops.h"
+#include "qemu/main-loop.h"
+#include "qemu/timer.h"
+#include "trace.h"
+
+#define TIMER_NR_REGS 4
+
+#define TIMER_CTRL_BITS 4
+#define TIMER_CTRL_MASK ((1 << TIMER_CTRL_BITS) - 1)
+
+#define TIMER_CLOCK_USE_EXT true
+#define TIMER_CLOCK_EXT_HZ 1000000
+#define TIMER_CLOCK_USE_APB false
+#define TIMER_CLOCK_APB_HZ 24000000
+
+#define TIMER_REG_STATUS 0
+#define TIMER_REG_RELOAD 1
+#define TIMER_REG_MATCH_FIRST 2
+#define TIMER_REG_MATCH_SECOND 3
+
+#define TIMER_FIRST_CAP_PULSE 4
+
+enum timer_ctrl_op {
+    op_enable = 0,
+    op_external_clock,
+    op_overflow_interrupt,
+    op_pulse_enable
+};
+
+/**
+ * Avoid mutual references between AspeedTimerCtrlState and AspeedTimer
+ * structs, as it's a waste of memory. The ptimer BH callback needs to know
+ * whether a specific AspeedTimer is enabled, but this information is held in
+ * AspeedTimerCtrlState. So, provide a helper to hoist ourselves from an
+ * arbitrary AspeedTimer to AspeedTimerCtrlState.
+ */
+static inline AspeedTimerCtrlState *timer_to_ctrl(AspeedTimer *t)
+{
+    const AspeedTimer (*timers)[] = (void *)t - (t->id * sizeof(*t));
+    return container_of(timers, AspeedTimerCtrlState, timers);
+}
+
+static inline bool timer_ctrl_status(AspeedTimer *t, enum timer_ctrl_op op)
+{
+    return !!(timer_to_ctrl(t)->ctrl & BIT(t->id * TIMER_CTRL_BITS + op));
+}
+
+static inline bool timer_enabled(AspeedTimer *t)
+{
+    return timer_ctrl_status(t, op_enable);
+}
+
+static inline bool timer_overflow_interrupt(AspeedTimer *t)
+{
+    return timer_ctrl_status(t, op_overflow_interrupt);
+}
+
+static inline bool timer_can_pulse(AspeedTimer *t)
+{
+    return t->id >= TIMER_FIRST_CAP_PULSE;
+}
+
+static void aspeed_timer_expire(void *opaque)
+{
+    AspeedTimer *t = opaque;
+
+    /* Only support interrupts on match values of zero for the moment - this is
+     * sufficient to boot an aspeed_defconfig Linux kernel.
+     *
+     * TODO: matching on arbitrary values (see e.g. hw/timer/a9gtimer.c)
+     */
+    bool match = !(t->match[0] && t->match[1]);
+    bool interrupt = timer_overflow_interrupt(t) || match;
+    if (timer_enabled(t) && interrupt) {
+        t->level = !t->level;
+        qemu_set_irq(t->irq, t->level);
+    }
+}
+
+static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
+{
+    uint64_t value;
+
+    switch (reg) {
+    case TIMER_REG_STATUS:
+        value = ptimer_get_count(t->timer);
+        break;
+    case TIMER_REG_RELOAD:
+        value = t->reload;
+        break;
+    case TIMER_REG_MATCH_FIRST:
+    case TIMER_REG_MATCH_SECOND:
+        value = t->match[reg - 2];
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n",
+                      __func__, reg);
+        value = 0;
+        break;
+    }
+    return value;
+}
+
+static uint64_t aspeed_timer_read(void *opaque, hwaddr offset, unsigned size)
+{
+    AspeedTimerCtrlState *s = opaque;
+    const int reg = (offset & 0xf) / 4;
+    uint64_t value;
+
+    switch (offset) {
+    case 0x30: /* Control Register */
+        value = s->ctrl;
+        break;
+    case 0x34: /* Control Register 2 */
+        value = s->ctrl2;
+        break;
+    case 0x00 ... 0x2c: /* Timers 1 - 4 */
+        value = aspeed_timer_get_value(&s->timers[(offset >> 4)], reg);
+        break;
+    case 0x40 ... 0x8c: /* Timers 5 - 8 */
+        value = aspeed_timer_get_value(&s->timers[(offset >> 4) - 1], reg);
+        break;
+    /* Illegal */
+    case 0x38:
+    case 0x3C:
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
+                __func__, offset);
+        value = 0;
+        break;
+    }
+    trace_aspeed_timer_read(offset, size, value);
+    return value;
+}
+
+static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
+                                   uint32_t value)
+{
+    AspeedTimer *t;
+
+    trace_aspeed_timer_set_value(timer, reg, value);
+    t = &s->timers[timer];
+    switch (reg) {
+    case TIMER_REG_STATUS:
+        if (timer_enabled(t)) {
+            ptimer_set_count(t->timer, value);
+        }
+        break;
+    case TIMER_REG_RELOAD:
+        t->reload = value;
+        ptimer_set_limit(t->timer, value, 1);
+        break;
+    case TIMER_REG_MATCH_FIRST:
+    case TIMER_REG_MATCH_SECOND:
+        if (value) {
+            /* Non-zero match values are unsupported. As such an interrupt will
+             * always be triggered when the timer reaches zero even if the
+             * overflow interrupt control bit is clear.
+             */
+            qemu_log_mask(LOG_UNIMP, "%s: Match value unsupported by device: "
+                    "0x%" PRIx32 "\n", __func__, value);
+        } else {
+            t->match[reg - 2] = value;
+        }
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n",
+                      __func__, reg);
+        break;
+    }
+}
+
+/* Control register operations are broken out into helpers that can be
+ * explictly called on aspeed_timer_reset(), but also from
+ * aspeed_timer_ctrl_op().
+ */
+
+static void aspeed_timer_ctrl_enable(AspeedTimer *t, bool enable)
+{
+    trace_aspeed_timer_ctrl_enable(t->id, enable);
+    if (enable) {
+        ptimer_run(t->timer, 0);
+    } else {
+        ptimer_stop(t->timer);
+        ptimer_set_limit(t->timer, t->reload, 1);
+    }
+}
+
+static void aspeed_timer_ctrl_external_clock(AspeedTimer *t, bool enable)
+{
+    trace_aspeed_timer_ctrl_external_clock(t->id, enable);
+    if (enable) {
+        ptimer_set_freq(t->timer, TIMER_CLOCK_EXT_HZ);
+    } else {
+        ptimer_set_freq(t->timer, TIMER_CLOCK_APB_HZ);
+    }
+}
+
+static void aspeed_timer_ctrl_overflow_interrupt(AspeedTimer *t, bool enable)
+{
+    trace_aspeed_timer_ctrl_overflow_interrupt(t->id, enable);
+}
+
+static void aspeed_timer_ctrl_pulse_enable(AspeedTimer *t, bool enable)
+{
+    if (timer_can_pulse(t)) {
+        trace_aspeed_timer_ctrl_pulse_enable(t->id, enable);
+    } else {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                "%s: Timer does not support pulse mode\n", __func__);
+    }
+}
+
+/**
+ * Given the actions are fixed in number and completely described in helper
+ * functions, dispatch with a lookup table rather than manage control flow with
+ * a switch statement.
+ */
+static void (*const ctrl_ops[])(AspeedTimer *, bool) = {
+    [op_enable] = aspeed_timer_ctrl_enable,
+    [op_external_clock] = aspeed_timer_ctrl_external_clock,
+    [op_overflow_interrupt] = aspeed_timer_ctrl_overflow_interrupt,
+    [op_pulse_enable] = aspeed_timer_ctrl_pulse_enable,
+};
+
+/**
+ * Conditionally affect changes chosen by a timer's control bit.
+ *
+ * The aspeed_timer_ctrl_op() interface is convenient for the
+ * aspeed_timer_set_ctrl() function as the "no change" early exit can be
+ * calculated for all operations, which cleans up the caller code. However the
+ * interface isn't convenient for the reset function where we want to enter a
+ * specific state without artificially constructing old and new values that
+ * will fall through the change guard (and motivates extracting the actions
+ * out to helper functions).
+ *
+ * @t: The timer to manipulate
+ * @op: The type of operation to be performed
+ * @old: The old state of the timer's control bits
+ * @new: The incoming state for the timer's control bits
+ */
+static void aspeed_timer_ctrl_op(AspeedTimer *t, enum timer_ctrl_op op,
+                                 uint8_t old, uint8_t new)
+{
+    const uint8_t mask = BIT(op);
+    const bool enable = !!(new & mask);
+    const bool changed = ((old ^ new) & mask);
+    if (!changed) {
+        return;
+    }
+    ctrl_ops[op](t, enable);
+}
+
+static void aspeed_timer_set_ctrl(AspeedTimerCtrlState *s, uint32_t reg)
+{
+    int i;
+    int shift;
+    uint8_t t_old, t_new;
+    AspeedTimer *t;
+    const uint8_t enable_mask = BIT(op_enable);
+
+    /* Handle a dependency between the 'enable' and remaining three
+     * configuration bits - i.e. if more than one bit in the control set has
+     * changed, including the 'enable' bit, then we want either disable the
+     * timer and perform configuration, or perform configuration and then
+     * enable the timer
+     */
+    for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
+        t = &s->timers[i];
+        shift = (i * TIMER_CTRL_BITS);
+        t_old = (s->ctrl >> shift) & TIMER_CTRL_MASK;
+        t_new = (reg >> shift) & TIMER_CTRL_MASK;
+
+        /* If we are disabling, do so first */
+        if ((t_old & enable_mask) && !(t_new & enable_mask)) {
+            aspeed_timer_ctrl_enable(t, false);
+        }
+        aspeed_timer_ctrl_op(t, op_external_clock, t_old, t_new);
+        aspeed_timer_ctrl_op(t, op_overflow_interrupt, t_old, t_new);
+        aspeed_timer_ctrl_op(t, op_pulse_enable, t_old, t_new);
+        /* If we are enabling, do so last */
+        if (!(t_old & enable_mask) && (t_new & enable_mask)) {
+            aspeed_timer_ctrl_enable(t, true);
+        }
+    }
+    s->ctrl = reg;
+}
+
+static void aspeed_timer_set_ctrl2(AspeedTimerCtrlState *s, uint32_t value)
+{
+    trace_aspeed_timer_set_ctrl2(value);
+}
+
+static void aspeed_timer_write(void *opaque, hwaddr offset, uint64_t value,
+                               unsigned size)
+{
+    const uint32_t tv = (uint32_t)(value & 0xFFFFFFFF);
+    const int reg = (offset & 0xf) / 4;
+    AspeedTimerCtrlState *s = opaque;
+
+    switch (offset) {
+    /* Control Registers */
+    case 0x30:
+        aspeed_timer_set_ctrl(s, tv);
+        break;
+    case 0x34:
+        aspeed_timer_set_ctrl2(s, tv);
+        break;
+    /* Timer Registers */
+    case 0x00 ... 0x2c:
+        aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS), reg, tv);
+        break;
+    case 0x40 ... 0x8c:
+        aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS) - 1, reg, tv);
+        break;
+    /* Illegal */
+    case 0x38:
+    case 0x3C:
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
+                __func__, offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps aspeed_timer_ops = {
+    .read = aspeed_timer_read,
+    .write = aspeed_timer_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+    .valid.unaligned = false,
+};
+
+static void aspeed_init_one_timer(AspeedTimerCtrlState *s, uint8_t id)
+{
+    QEMUBH *bh;
+    AspeedTimer *t = &s->timers[id];
+
+    t->id = id;
+    bh = qemu_bh_new(aspeed_timer_expire, t);
+    t->timer = ptimer_init(bh);
+}
+
+static void aspeed_timer_realize(DeviceState *dev, Error **errp)
+{
+    int i;
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
+
+    for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
+        aspeed_init_one_timer(s, i);
+        sysbus_init_irq(sbd, &s->timers[i].irq);
+    }
+    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_timer_ops, s,
+                          TYPE_ASPEED_TIMER, 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static void aspeed_timer_reset(DeviceState *dev)
+{
+    int i;
+    AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
+
+    for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
+        AspeedTimer *t = &s->timers[i];
+        /* Explictly call helpers to avoid any conditional behaviour through
+         * aspeed_timer_set_ctrl().
+         */
+        aspeed_timer_ctrl_enable(t, false);
+        aspeed_timer_ctrl_external_clock(t, TIMER_CLOCK_USE_APB);
+        aspeed_timer_ctrl_overflow_interrupt(t, false);
+        aspeed_timer_ctrl_pulse_enable(t, false);
+        t->level = 0;
+        t->reload = 0;
+        t->match[0] = 0;
+        t->match[1] = 0;
+    }
+    s->ctrl = 0;
+    s->ctrl2 = 0;
+}
+
+static const VMStateDescription vmstate_aspeed_timer = {
+    .name = "aspeed.timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(id, AspeedTimer),
+        VMSTATE_INT32(level, AspeedTimer),
+        VMSTATE_PTIMER(timer, AspeedTimer),
+        VMSTATE_UINT32(reload, AspeedTimer),
+        VMSTATE_UINT32_ARRAY(match, AspeedTimer, 2),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_aspeed_timer_state = {
+    .name = "aspeed.timerctrl",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(ctrl, AspeedTimerCtrlState),
+        VMSTATE_UINT32(ctrl2, AspeedTimerCtrlState),
+        VMSTATE_STRUCT_ARRAY(timers, AspeedTimerCtrlState,
+                             ASPEED_TIMER_NR_TIMERS, 1, vmstate_aspeed_timer,
+                             AspeedTimer),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = aspeed_timer_realize;
+    dc->reset = aspeed_timer_reset;
+    dc->desc = "ASPEED Timer";
+    dc->vmsd = &vmstate_aspeed_timer_state;
+}
+
+static const TypeInfo aspeed_timer_info = {
+    .name = TYPE_ASPEED_TIMER,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(AspeedTimerCtrlState),
+    .class_init = timer_class_init,
+};
+
+static void aspeed_timer_register_types(void)
+{
+    type_register_static(&aspeed_timer_info);
+}
+
+type_init(aspeed_timer_register_types)
diff --git a/include/hw/timer/aspeed_timer.h b/include/hw/timer/aspeed_timer.h
new file mode 100644
index 0000000..44dc2f8
--- /dev/null
+++ b/include/hw/timer/aspeed_timer.h
@@ -0,0 +1,59 @@
+/*
+ *  ASPEED AST2400 Timer
+ *
+ *  Andrew Jeffery <andrew@aj.id.au>
+ *
+ *  Copyright (C) 2016 IBM Corp.
+ *
+ *  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, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef ASPEED_TIMER_H
+#define ASPEED_TIMER_H
+
+#include "hw/ptimer.h"
+
+#define ASPEED_TIMER(obj) \
+    OBJECT_CHECK(AspeedTimerCtrlState, (obj), TYPE_ASPEED_TIMER);
+#define TYPE_ASPEED_TIMER "aspeed.timer"
+#define ASPEED_TIMER_NR_TIMERS 8
+
+typedef struct AspeedTimer {
+    qemu_irq irq;
+
+    uint8_t id;
+
+    /**
+     * Track the line level as the ASPEED timers implement edge triggered
+     * interrupts, signalling with both the rising and falling edge.
+     */
+    int32_t level;
+    ptimer_state *timer;
+    uint32_t reload;
+    uint32_t match[2];
+} AspeedTimer;
+
+typedef struct AspeedTimerCtrlState {
+    /*< private >*/
+    SysBusDevice parent;
+
+    /*< public >*/
+    MemoryRegion iomem;
+
+    uint32_t ctrl;
+    uint32_t ctrl2;
+    AspeedTimer timers[ASPEED_TIMER_NR_TIMERS];
+} AspeedTimerCtrlState;
+
+#endif /* ASPEED_TIMER_H */
diff --git a/trace-events b/trace-events
index 0ad8a1c..e589230 100644
--- a/trace-events
+++ b/trace-events
@@ -1892,3 +1892,12 @@ qio_channel_command_new_pid(void *ioc, int writefd, int readfd, int pid) "Comman
 qio_channel_command_new_spawn(void *ioc, const char *binary, int flags) "Command new spawn ioc=%p binary=%s flags=%d"
 qio_channel_command_abort(void *ioc, int pid) "Command abort ioc=%p pid=%d"
 qio_channel_command_wait(void *ioc, int pid, int ret, int status) "Command abort ioc=%p pid=%d ret=%d status=%d"
+
+# hw/timer/aspeed_timer.c
+aspeed_timer_ctrl_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
+aspeed_timer_ctrl_external_clock(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
+aspeed_timer_ctrl_overflow_interrupt(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
+aspeed_timer_ctrl_pulse_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
+aspeed_timer_set_ctrl2(uint32_t value) "Value: 0x%" PRIx32
+aspeed_timer_set_value(int timer, int reg, uint32_t value) "Timer %d register %d: 0x%" PRIx32
+aspeed_timer_read(uint64_t offset, unsigned size, uint64_t value) "From 0x%" PRIx64 ": of size %u: 0x%" PRIx64
-- 
1.9.1

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

* [Qemu-devel] [PULL 13/21] hw/intc: Add (new) ASPEED VIC device model
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (11 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 12/21] hw/timer: Add ASPEED timer device model Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 14/21] hw/arm: Add ASPEED AST2400 SoC model Peter Maydell
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Jeffery <andrew@aj.id.au>

Implement a basic ASPEED VIC device model for the AST2400 SoC[1], with
enough functionality to boot an aspeed_defconfig Linux kernel. The model
implements the 'new' (revised) register set: While the hardware exposes
both the new and legacy register sets, accesses to the model's legacy
register set will not be serviced (however the access will be logged).

[1] http://www.aspeedtech.com/products.php?fPath=20&rId=376

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1458096317-25223-3-git-send-email-andrew@aj.id.au
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/Makefile.objs        |   1 +
 hw/intc/aspeed_vic.c         | 339 +++++++++++++++++++++++++++++++++++++++++++
 include/hw/intc/aspeed_vic.h |  48 ++++++
 trace-events                 |   7 +
 4 files changed, 395 insertions(+)
 create mode 100644 hw/intc/aspeed_vic.c
 create mode 100644 include/hw/intc/aspeed_vic.h

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 6a13a39..0e47f0f 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -31,3 +31,4 @@ obj-$(CONFIG_XICS_KVM) += xics_kvm.o
 obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
 obj-$(CONFIG_S390_FLIC) += s390_flic.o
 obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c
new file mode 100644
index 0000000..19a0ff7
--- /dev/null
+++ b/hw/intc/aspeed_vic.c
@@ -0,0 +1,339 @@
+/*
+ * ASPEED Interrupt Controller (New)
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ *
+ * Copyright 2015, 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+/* The hardware exposes two register sets, a legacy set and a 'new' set. The
+ * model implements the 'new' register set, and logs warnings on accesses to
+ * the legacy IO space.
+ *
+ * The hardware uses 32bit registers to manage 51 IRQs, with low and high
+ * registers for each conceptual register. The device model's implementation
+ * uses 64bit data types to store both low and high register values (in the one
+ * member), but must cope with access offset values in multiples of 4 passed to
+ * the callbacks. As such the read() and write() implementations process the
+ * provided offset to understand whether the access is requesting the lower or
+ * upper 32 bits of the 64bit member.
+ *
+ * Additionally, the "Interrupt Enable", "Edge Status" and "Software Interrupt"
+ * fields have separate "enable"/"status" and "clear" registers, where set bits
+ * are written to one or the other to change state (avoiding a
+ * read-modify-write sequence).
+ */
+
+#include "qemu/osdep.h"
+#include <inttypes.h>
+#include "hw/intc/aspeed_vic.h"
+#include "qemu/bitops.h"
+#include "trace.h"
+
+#define AVIC_NEW_BASE_OFFSET 0x80
+
+#define AVIC_L_MASK 0xFFFFFFFFU
+#define AVIC_H_MASK 0x0007FFFFU
+#define AVIC_EVENT_W_MASK (0x78000ULL << 32)
+
+static void aspeed_vic_update(AspeedVICState *s)
+{
+    uint64_t new = (s->raw & s->enable);
+    uint64_t flags;
+
+    flags = new & s->select;
+    trace_aspeed_vic_update_fiq(!!flags);
+    qemu_set_irq(s->fiq, !!flags);
+
+    flags = new & ~s->select;
+    trace_aspeed_vic_update_irq(!!flags);
+    qemu_set_irq(s->irq, !!flags);
+}
+
+static void aspeed_vic_set_irq(void *opaque, int irq, int level)
+{
+    uint64_t irq_mask;
+    bool raise;
+    AspeedVICState *s = (AspeedVICState *)opaque;
+
+    if (irq > ASPEED_VIC_NR_IRQS) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+                      __func__, irq);
+        return;
+    }
+
+    trace_aspeed_vic_set_irq(irq, level);
+
+    irq_mask = BIT(irq);
+    if (s->sense & irq_mask) {
+        /* level-triggered */
+        if (s->event & irq_mask) {
+            /* high-sensitive */
+            raise = level;
+        } else {
+            /* low-sensitive */
+            raise = !level;
+        }
+        s->raw = deposit64(s->raw, irq, 1, raise);
+    } else {
+        uint64_t old_level = s->level & irq_mask;
+
+        /* edge-triggered */
+        if (s->dual_edge & irq_mask) {
+            raise = (!!old_level) != (!!level);
+        } else {
+            if (s->event & irq_mask) {
+                /* rising-sensitive */
+                raise = !old_level && level;
+            } else {
+                /* falling-sensitive */
+                raise = old_level && !level;
+            }
+        }
+        if (raise) {
+            s->raw = deposit64(s->raw, irq, 1, raise);
+        }
+    }
+    s->level = deposit64(s->level, irq, 1, level);
+    aspeed_vic_update(s);
+}
+
+static uint64_t aspeed_vic_read(void *opaque, hwaddr offset, unsigned size)
+{
+    uint64_t val;
+    const bool high = !!(offset & 0x4);
+    hwaddr n_offset = (offset & ~0x4);
+    AspeedVICState *s = (AspeedVICState *)opaque;
+
+    if (offset < AVIC_NEW_BASE_OFFSET) {
+        qemu_log_mask(LOG_UNIMP, "%s: Ignoring read from legacy registers "
+                      "at 0x%" HWADDR_PRIx "[%u]\n", __func__, offset, size);
+        return 0;
+    }
+
+    n_offset -= AVIC_NEW_BASE_OFFSET;
+
+    switch (n_offset) {
+    case 0x0: /* IRQ Status */
+        val = s->raw & ~s->select & s->enable;
+        break;
+    case 0x08: /* FIQ Status */
+        val = s->raw & s->select & s->enable;
+        break;
+    case 0x10: /* Raw Interrupt Status */
+        val = s->raw;
+        break;
+    case 0x18: /* Interrupt Selection */
+        val = s->select;
+        break;
+    case 0x20: /* Interrupt Enable */
+        val = s->enable;
+        break;
+    case 0x30: /* Software Interrupt */
+        val = s->trigger;
+        break;
+    case 0x40: /* Interrupt Sensitivity */
+        val = s->sense;
+        break;
+    case 0x48: /* Interrupt Both Edge Trigger Control */
+        val = s->dual_edge;
+        break;
+    case 0x50: /* Interrupt Event */
+        val = s->event;
+        break;
+    case 0x60: /* Edge Triggered Interrupt Status */
+        val = s->raw & ~s->sense;
+        break;
+        /* Illegal */
+    case 0x28: /* Interrupt Enable Clear */
+    case 0x38: /* Software Interrupt Clear */
+    case 0x58: /* Edge Triggered Interrupt Clear */
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Read of write-only register with offset 0x%"
+                      HWADDR_PRIx "\n", __func__, offset);
+        val = 0;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad register at offset 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+        val = 0;
+        break;
+    }
+    if (high) {
+        val = extract64(val, 32, 19);
+    }
+    trace_aspeed_vic_read(offset, size, val);
+    return val;
+}
+
+static void aspeed_vic_write(void *opaque, hwaddr offset, uint64_t data,
+                             unsigned size)
+{
+    const bool high = !!(offset & 0x4);
+    hwaddr n_offset = (offset & ~0x4);
+    AspeedVICState *s = (AspeedVICState *)opaque;
+
+    if (offset < AVIC_NEW_BASE_OFFSET) {
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: Ignoring write to legacy registers at 0x%"
+                      HWADDR_PRIx "[%u] <- 0x%" PRIx64 "\n", __func__, offset,
+                      size, data);
+        return;
+    }
+
+    n_offset -= AVIC_NEW_BASE_OFFSET;
+    trace_aspeed_vic_write(offset, size, data);
+
+    /* Given we have members using separate enable/clear registers, deposit64()
+     * isn't quite the tool for the job. Instead, relocate the incoming bits to
+     * the required bit offset based on the provided access address
+     */
+    if (high) {
+        data &= AVIC_H_MASK;
+        data <<= 32;
+    } else {
+        data &= AVIC_L_MASK;
+    }
+
+    switch (n_offset) {
+    case 0x18: /* Interrupt Selection */
+        /* Register has deposit64() semantics - overwrite requested 32 bits */
+        if (high) {
+            s->select &= AVIC_L_MASK;
+        } else {
+            s->select &= ((uint64_t) AVIC_H_MASK) << 32;
+        }
+        s->select |= data;
+        break;
+    case 0x20: /* Interrupt Enable */
+        s->enable |= data;
+        break;
+    case 0x28: /* Interrupt Enable Clear */
+        s->enable &= ~data;
+        break;
+    case 0x30: /* Software Interrupt */
+        qemu_log_mask(LOG_UNIMP, "%s: Software interrupts unavailable. "
+                      "IRQs requested: 0x%016" PRIx64 "\n", __func__, data);
+        break;
+    case 0x38: /* Software Interrupt Clear */
+        qemu_log_mask(LOG_UNIMP, "%s: Software interrupts unavailable. "
+                      "IRQs to be cleared: 0x%016" PRIx64 "\n", __func__, data);
+        break;
+    case 0x50: /* Interrupt Event */
+        /* Register has deposit64() semantics - overwrite the top four valid
+         * IRQ bits, as only the top four IRQs (GPIOs) can change their event
+         * type */
+        if (high) {
+            s->event &= ~AVIC_EVENT_W_MASK;
+            s->event |= (data & AVIC_EVENT_W_MASK);
+        } else {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "Ignoring invalid write to interrupt event register");
+        }
+        break;
+    case 0x58: /* Edge Triggered Interrupt Clear */
+        s->raw &= ~(data & ~s->sense);
+        break;
+    case 0x00: /* IRQ Status */
+    case 0x08: /* FIQ Status */
+    case 0x10: /* Raw Interrupt Status */
+    case 0x40: /* Interrupt Sensitivity */
+    case 0x48: /* Interrupt Both Edge Trigger Control */
+    case 0x60: /* Edge Triggered Interrupt Status */
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Write of read-only register with offset 0x%"
+                      HWADDR_PRIx "\n", __func__, offset);
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad register at offset 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+        break;
+    }
+    aspeed_vic_update(s);
+}
+
+static const MemoryRegionOps aspeed_vic_ops = {
+    .read = aspeed_vic_read,
+    .write = aspeed_vic_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+    .valid.unaligned = false,
+};
+
+static void aspeed_vic_reset(DeviceState *dev)
+{
+    AspeedVICState *s = ASPEED_VIC(dev);
+
+    s->level = 0;
+    s->raw = 0;
+    s->select = 0;
+    s->enable = 0;
+    s->trigger = 0;
+    s->sense = 0x1F07FFF8FFFFULL;
+    s->dual_edge = 0xF800070000ULL;
+    s->event = 0x5F07FFF8FFFFULL;
+}
+
+#define AVIC_IO_REGION_SIZE 0x20000
+
+static void aspeed_vic_realize(DeviceState *dev, Error **errp)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    AspeedVICState *s = ASPEED_VIC(dev);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_vic_ops, s,
+                          TYPE_ASPEED_VIC, AVIC_IO_REGION_SIZE);
+
+    sysbus_init_mmio(sbd, &s->iomem);
+
+    qdev_init_gpio_in(dev, aspeed_vic_set_irq, ASPEED_VIC_NR_IRQS);
+    sysbus_init_irq(sbd, &s->irq);
+    sysbus_init_irq(sbd, &s->fiq);
+}
+
+static const VMStateDescription vmstate_aspeed_vic = {
+    .name = "aspeed.new-vic",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64(level, AspeedVICState),
+        VMSTATE_UINT64(raw, AspeedVICState),
+        VMSTATE_UINT64(select, AspeedVICState),
+        VMSTATE_UINT64(enable, AspeedVICState),
+        VMSTATE_UINT64(trigger, AspeedVICState),
+        VMSTATE_UINT64(sense, AspeedVICState),
+        VMSTATE_UINT64(dual_edge, AspeedVICState),
+        VMSTATE_UINT64(event, AspeedVICState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void aspeed_vic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->realize = aspeed_vic_realize;
+    dc->reset = aspeed_vic_reset;
+    dc->desc = "ASPEED Interrupt Controller (New)";
+    dc->vmsd = &vmstate_aspeed_vic;
+}
+
+static const TypeInfo aspeed_vic_info = {
+    .name = TYPE_ASPEED_VIC,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(AspeedVICState),
+    .class_init = aspeed_vic_class_init,
+};
+
+static void aspeed_vic_register_types(void)
+{
+    type_register_static(&aspeed_vic_info);
+}
+
+type_init(aspeed_vic_register_types);
diff --git a/include/hw/intc/aspeed_vic.h b/include/hw/intc/aspeed_vic.h
new file mode 100644
index 0000000..107ff17
--- /dev/null
+++ b/include/hw/intc/aspeed_vic.h
@@ -0,0 +1,48 @@
+/*
+ * ASPEED Interrupt Controller (New)
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Need to add SVIC and CVIC support
+ */
+#ifndef ASPEED_VIC_H
+#define ASPEED_VIC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ASPEED_VIC "aspeed.vic"
+#define ASPEED_VIC(obj) OBJECT_CHECK(AspeedVICState, (obj), TYPE_ASPEED_VIC)
+
+#define ASPEED_VIC_NR_IRQS 51
+
+typedef struct AspeedVICState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    MemoryRegion iomem;
+    qemu_irq irq;
+    qemu_irq fiq;
+
+    uint64_t level;
+    uint64_t raw;
+    uint64_t select;
+    uint64_t enable;
+    uint64_t trigger;
+
+    /* 0=edge, 1=level */
+    uint64_t sense;
+
+    /* 0=single-edge, 1=dual-edge */
+    uint64_t dual_edge;
+
+    /* 0=low-sensitive/falling-edge, 1=high-sensitive/rising-edge */
+    uint64_t event;
+} AspeedVICState;
+
+#endif /* ASPEED_VIC_H */
diff --git a/trace-events b/trace-events
index e589230..d494de1 100644
--- a/trace-events
+++ b/trace-events
@@ -1901,3 +1901,10 @@ aspeed_timer_ctrl_pulse_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
 aspeed_timer_set_ctrl2(uint32_t value) "Value: 0x%" PRIx32
 aspeed_timer_set_value(int timer, int reg, uint32_t value) "Timer %d register %d: 0x%" PRIx32
 aspeed_timer_read(uint64_t offset, unsigned size, uint64_t value) "From 0x%" PRIx64 ": of size %u: 0x%" PRIx64
+
+# hw/intc/aspeed_vic.c
+aspeed_vic_set_irq(int irq, int level) "Enabling IRQ %d: %d"
+aspeed_vic_update_fiq(int flags) "Raising FIQ: %d"
+aspeed_vic_update_irq(int flags) "Raising IRQ: %d"
+aspeed_vic_read(uint64_t offset, unsigned size, uint32_t value) "From 0x%" PRIx64 " of size %u: 0x%" PRIx32
+aspeed_vic_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
-- 
1.9.1

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

* [Qemu-devel] [PULL 14/21] hw/arm: Add ASPEED AST2400 SoC model
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (12 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 13/21] hw/intc: Add (new) ASPEED VIC " Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 15/21] hw/arm: Add palmetto-bmc machine Peter Maydell
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Jeffery <andrew@aj.id.au>

While the ASPEED AST2400 SoC[1] has a broad range of capabilities this
implementation is minimal, comprising an ARM926 processor, ASPEED VIC
and timer devices, and a 8250 UART.

[1] http://www.aspeedtech.com/products.php?fPath=20&rId=376

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1458096317-25223-4-git-send-email-andrew@aj.id.au
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/Makefile.objs     |   1 +
 hw/arm/ast2400.c         | 137 +++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/ast2400.h |  35 ++++++++++++
 3 files changed, 173 insertions(+)
 create mode 100644 hw/arm/ast2400.c
 create mode 100644 include/hw/arm/ast2400.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index a711e4d..f333b7f 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -16,3 +16,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_ASPEED_SOC) += ast2400.o
diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
new file mode 100644
index 0000000..daa5518
--- /dev/null
+++ b/hw/arm/ast2400.c
@@ -0,0 +1,137 @@
+/*
+ * AST2400 SoC
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ * Jeremy Kerr <jk@ozlabs.org>
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "exec/address-spaces.h"
+#include "hw/arm/ast2400.h"
+#include "hw/char/serial.h"
+
+#define AST2400_UART_5_BASE      0x00184000
+#define AST2400_IOMEM_SIZE       0x00200000
+#define AST2400_IOMEM_BASE       0x1E600000
+#define AST2400_VIC_BASE         0x1E6C0000
+#define AST2400_TIMER_BASE       0x1E782000
+
+static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
+static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
+
+/*
+ * IO handlers: simply catch any reads/writes to IO addresses that aren't
+ * handled by a device mapping.
+ */
+
+static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned size)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
+                  __func__, offset, size);
+    return 0;
+}
+
+static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t value,
+                unsigned size)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
+                  __func__, offset, value, size);
+}
+
+static const MemoryRegionOps ast2400_io_ops = {
+    .read = ast2400_io_read,
+    .write = ast2400_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void ast2400_init(Object *obj)
+{
+    AST2400State *s = AST2400(obj);
+
+    s->cpu = cpu_arm_init("arm926");
+
+    object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
+    object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
+    qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
+
+    object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
+    object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
+    qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
+}
+
+static void ast2400_realize(DeviceState *dev, Error **errp)
+{
+    int i;
+    AST2400State *s = AST2400(dev);
+    Error *err = NULL;
+
+    /* IO space */
+    memory_region_init_io(&s->iomem, NULL, &ast2400_io_ops, NULL,
+            "ast2400.io", AST2400_IOMEM_SIZE);
+    memory_region_add_subregion_overlap(get_system_memory(), AST2400_IOMEM_BASE,
+            &s->iomem, -1);
+
+    /* VIC */
+    object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, AST2400_VIC_BASE);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
+                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
+                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
+
+    /* Timer */
+    object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, AST2400_TIMER_BASE);
+    for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
+        qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
+    }
+
+    /* UART - attach an 8250 to the IO space as our UART5 */
+    if (serial_hds[0]) {
+        qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
+        serial_mm_init(&s->iomem, AST2400_UART_5_BASE, 2,
+                       uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
+    }
+}
+
+static void ast2400_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ast2400_realize;
+
+    /*
+     * Reason: creates an ARM CPU, thus use after free(), see
+     * arm_cpu_class_init()
+     */
+    dc->cannot_destroy_with_object_finalize_yet = true;
+}
+
+static const TypeInfo ast2400_type_info = {
+    .name = TYPE_AST2400,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(AST2400State),
+    .instance_init = ast2400_init,
+    .class_init = ast2400_class_init,
+};
+
+static void ast2400_register_types(void)
+{
+    type_register_static(&ast2400_type_info);
+}
+
+type_init(ast2400_register_types)
diff --git a/include/hw/arm/ast2400.h b/include/hw/arm/ast2400.h
new file mode 100644
index 0000000..f16a1ed
--- /dev/null
+++ b/include/hw/arm/ast2400.h
@@ -0,0 +1,35 @@
+/*
+ * ASPEED AST2400 SoC
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef AST2400_H
+#define AST2400_H
+
+#include "hw/arm/arm.h"
+#include "hw/intc/aspeed_vic.h"
+#include "hw/timer/aspeed_timer.h"
+
+typedef struct AST2400State {
+    /*< private >*/
+    DeviceState parent;
+
+    /*< public >*/
+    ARMCPU *cpu;
+    MemoryRegion iomem;
+    AspeedVICState vic;
+    AspeedTimerCtrlState timerctrl;
+} AST2400State;
+
+#define TYPE_AST2400 "ast2400"
+#define AST2400(obj) OBJECT_CHECK(AST2400State, (obj), TYPE_AST2400)
+
+#define AST2400_SDRAM_BASE       0x40000000
+
+#endif /* AST2400_H */
-- 
1.9.1

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

* [Qemu-devel] [PULL 15/21] hw/arm: Add palmetto-bmc machine
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (13 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 14/21] hw/arm: Add ASPEED AST2400 SoC model Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 16/21] bcm2835_peripherals: enable sdhci pending-insert quirk for raspberry pi Peter Maydell
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Jeffery <andrew@aj.id.au>

The new machine is a thin layer over the AST2400 ARM926-based SoC[1].
Between the minimal machine and the current SoC implementation there is
enough functionality to boot an aspeed_defconfig Linux kernel to
userspace. Nothing yet is specific to the Palmetto's BMC (other than
using an AST2400 SoC), but creating specific machine types is preferable
to a generic machine that doesn't match any particular hardware.

[1] http://www.aspeedtech.com/products.php?fPath=20&rId=376

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1458096317-25223-5-git-send-email-andrew@aj.id.au
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/Makefile.objs  |  2 +-
 hw/arm/palmetto-bmc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/palmetto-bmc.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index f333b7f..954c9fe 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -16,4 +16,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_ASPEED_SOC) += ast2400.o
+obj-$(CONFIG_ASPEED_SOC) += ast2400.o palmetto-bmc.o
diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
new file mode 100644
index 0000000..55d7419
--- /dev/null
+++ b/hw/arm/palmetto-bmc.c
@@ -0,0 +1,65 @@
+/*
+ * OpenPOWER Palmetto BMC
+ *
+ * Andrew Jeffery <andrew@aj.id.au>
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "exec/address-spaces.h"
+#include "hw/arm/arm.h"
+#include "hw/arm/ast2400.h"
+#include "hw/boards.h"
+
+static struct arm_boot_info palmetto_bmc_binfo = {
+    .loader_start = AST2400_SDRAM_BASE,
+    .board_id = 0,
+    .nb_cpus = 1,
+};
+
+typedef struct PalmettoBMCState {
+    AST2400State soc;
+    MemoryRegion ram;
+} PalmettoBMCState;
+
+static void palmetto_bmc_init(MachineState *machine)
+{
+    PalmettoBMCState *bmc;
+
+    bmc = g_new0(PalmettoBMCState, 1);
+    object_initialize(&bmc->soc, (sizeof(bmc->soc)), TYPE_AST2400);
+    object_property_add_child(OBJECT(machine), "soc", OBJECT(&bmc->soc),
+                              &error_abort);
+
+    memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
+    memory_region_add_subregion(get_system_memory(), AST2400_SDRAM_BASE,
+                                &bmc->ram);
+    object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
+                                   &error_abort);
+    object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
+                             &error_abort);
+
+    palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
+    palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
+    palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
+    palmetto_bmc_binfo.ram_size = ram_size;
+    arm_load_kernel(ARM_CPU(first_cpu), &palmetto_bmc_binfo);
+}
+
+static void palmetto_bmc_machine_init(MachineClass *mc)
+{
+    mc->desc = "OpenPOWER Palmetto BMC";
+    mc->init = palmetto_bmc_init;
+    mc->max_cpus = 1;
+    mc->no_sdcard = 1;
+    mc->no_floppy = 1;
+    mc->no_cdrom = 1;
+    mc->no_sdcard = 1;
+    mc->no_parallel = 1;
+}
+
+DEFINE_MACHINE("palmetto-bmc", palmetto_bmc_machine_init);
-- 
1.9.1

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

* [Qemu-devel] [PULL 16/21] bcm2835_peripherals: enable sdhci pending-insert quirk for raspberry pi
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (14 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 15/21] hw/arm: Add palmetto-bmc machine Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 17/21] bcm2835_aux: add emulation of BCM2835 AUX (aka UART1) block Peter Maydell
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Baumann <Andrew.Baumann@microsoft.com>

Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1457467526-8840-2-git-send-email-Andrew.Baumann@microsoft.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/bcm2835_peripherals.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 6d66fa0..6ce9cd1 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -171,6 +171,13 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    object_property_set_bool(OBJECT(&s->sdhci), true, "pending-insert-quirk",
+                             &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
     object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
-- 
1.9.1

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

* [Qemu-devel] [PULL 17/21] bcm2835_aux: add emulation of BCM2835 AUX (aka UART1) block
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (15 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 16/21] bcm2835_peripherals: enable sdhci pending-insert quirk for raspberry pi Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 18/21] bcm2835_fb: add framebuffer device for Raspberry Pi Peter Maydell
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Baumann <Andrew.Baumann@microsoft.com>

At present only the core UART functions (data path for tx/rx) are
implemented, which is enough for UEFI to boot. The following
features/registers are unimplemented:
  * Line/modem control
  * Scratch register
  * Extra control
  * Baudrate
  * SPI interfaces

Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1457467526-8840-3-git-send-email-Andrew.Baumann@microsoft.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/bcm2835_peripherals.c         |  32 ++++
 hw/char/Makefile.objs                |   1 +
 hw/char/bcm2835_aux.c                | 316 +++++++++++++++++++++++++++++++++++
 include/hw/arm/bcm2835_peripherals.h |   2 +
 include/hw/char/bcm2835_aux.h        |  33 ++++
 5 files changed, 384 insertions(+)
 create mode 100644 hw/char/bcm2835_aux.c
 create mode 100644 include/hw/char/bcm2835_aux.h

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 6ce9cd1..d6453cc 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -12,6 +12,7 @@
 #include "hw/arm/bcm2835_peripherals.h"
 #include "hw/misc/bcm2835_mbox_defs.h"
 #include "hw/arm/raspi_platform.h"
+#include "sysemu/char.h"
 
 /* Peripheral base address on the VC (GPU) system bus */
 #define BCM2835_VC_PERI_BASE 0x7e000000
@@ -48,6 +49,11 @@ static void bcm2835_peripherals_init(Object *obj)
     object_property_add_child(obj, "uart0", OBJECT(s->uart0), NULL);
     qdev_set_parent_bus(DEVICE(s->uart0), sysbus_get_default());
 
+    /* AUX / UART1 */
+    object_initialize(&s->aux, sizeof(s->aux), TYPE_BCM2835_AUX);
+    object_property_add_child(obj, "aux", OBJECT(&s->aux), NULL);
+    qdev_set_parent_bus(DEVICE(&s->aux), sysbus_get_default());
+
     /* Mailboxes */
     object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX);
     object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL);
@@ -79,6 +85,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
     MemoryRegion *ram;
     Error *err = NULL;
     uint32_t ram_size;
+    CharDriverState *chr;
     int n;
 
     obj = object_property_get_link(OBJECT(dev), "ram", &err);
@@ -131,6 +138,29 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
         qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
                                INTERRUPT_UART));
 
+    /* AUX / UART1 */
+    /* TODO: don't call qemu_char_get_next_serial() here, instead set
+     * chardev properties for each uart at the board level, once pl011
+     * (uart0) has been updated to avoid qemu_char_get_next_serial()
+     */
+    chr = qemu_char_get_next_serial();
+    if (chr == NULL) {
+        chr = qemu_chr_new("bcm2835.uart1", "null", NULL);
+    }
+    qdev_prop_set_chr(DEVICE(&s->aux), "chardev", chr);
+
+    object_property_set_bool(OBJECT(&s->aux), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    memory_region_add_subregion(&s->peri_mr, UART1_OFFSET,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->aux), 0));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->aux), 0,
+        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+                               INTERRUPT_AUX));
+
     /* Mailboxes */
     object_property_set_bool(OBJECT(&s->mboxes), true, "realized", &err);
     if (err) {
@@ -203,6 +233,8 @@ static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
     DeviceClass *dc = DEVICE_CLASS(oc);
 
     dc->realize = bcm2835_peripherals_realize;
+    /* Reason: realize() method uses qemu_char_get_next_serial() */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo bcm2835_peripherals_type_info = {
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 5931cc8..69a553c 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -16,6 +16,7 @@ obj-$(CONFIG_SH4) += sh_serial.o
 obj-$(CONFIG_PSERIES) += spapr_vty.o
 obj-$(CONFIG_DIGIC) += digic-uart.o
 obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
+obj-$(CONFIG_RASPI) += bcm2835_aux.o
 
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
 common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
new file mode 100644
index 0000000..0394d11
--- /dev/null
+++ b/hw/char/bcm2835_aux.c
@@ -0,0 +1,316 @@
+/*
+ * BCM2835 (Raspberry Pi / Pi 2) Aux block (mini UART and SPI).
+ * Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ * Based on pl011.c, copyright terms below:
+ *
+ * Arm PrimeCell PL011 UART
+ *
+ * Copyright (c) 2006 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This code is licensed under the GPL.
+ *
+ * At present only the core UART functions (data path for tx/rx) are
+ * implemented. The following features/registers are unimplemented:
+ *  - Line/modem control
+ *  - Scratch register
+ *  - Extra control
+ *  - Baudrate
+ *  - SPI interfaces
+ */
+
+#include "qemu/osdep.h"
+#include "hw/char/bcm2835_aux.h"
+
+#define AUX_IRQ         0x0
+#define AUX_ENABLES     0x4
+#define AUX_MU_IO_REG   0x40
+#define AUX_MU_IER_REG  0x44
+#define AUX_MU_IIR_REG  0x48
+#define AUX_MU_LCR_REG  0x4c
+#define AUX_MU_MCR_REG  0x50
+#define AUX_MU_LSR_REG  0x54
+#define AUX_MU_MSR_REG  0x58
+#define AUX_MU_SCRATCH  0x5c
+#define AUX_MU_CNTL_REG 0x60
+#define AUX_MU_STAT_REG 0x64
+#define AUX_MU_BAUD_REG 0x68
+
+/* bits in IER/IIR registers */
+#define TX_INT  0x1
+#define RX_INT  0x2
+
+static void bcm2835_aux_update(BCM2835AuxState *s)
+{
+    /* signal an interrupt if either:
+     * 1. rx interrupt is enabled and we have a non-empty rx fifo, or
+     * 2. the tx interrupt is enabled (since we instantly drain the tx fifo)
+     */
+    s->iir = 0;
+    if ((s->ier & RX_INT) && s->read_count != 0) {
+        s->iir |= RX_INT;
+    }
+    if (s->ier & TX_INT) {
+        s->iir |= TX_INT;
+    }
+    qemu_set_irq(s->irq, s->iir != 0);
+}
+
+static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
+{
+    BCM2835AuxState *s = opaque;
+    uint32_t c, res;
+
+    switch (offset) {
+    case AUX_IRQ:
+        return s->iir != 0;
+
+    case AUX_ENABLES:
+        return 1; /* mini UART permanently enabled */
+
+    case AUX_MU_IO_REG:
+        /* "DLAB bit set means access baudrate register" is NYI */
+        c = s->read_fifo[s->read_pos];
+        if (s->read_count > 0) {
+            s->read_count--;
+            if (++s->read_pos == BCM2835_AUX_RX_FIFO_LEN) {
+                s->read_pos = 0;
+            }
+        }
+        if (s->chr) {
+            qemu_chr_accept_input(s->chr);
+        }
+        bcm2835_aux_update(s);
+        return c;
+
+    case AUX_MU_IER_REG:
+        /* "DLAB bit set means access baudrate register" is NYI */
+        return 0xc0 | s->ier; /* FIFO enables always read 1 */
+
+    case AUX_MU_IIR_REG:
+        res = 0xc0; /* FIFO enables */
+        /* The spec is unclear on what happens when both tx and rx
+         * interrupts are active, besides that this cannot occur. At
+         * present, we choose to prioritise the rx interrupt, since
+         * the tx fifo is always empty. */
+        if (s->read_count != 0) {
+            res |= 0x4;
+        } else {
+            res |= 0x2;
+        }
+        if (s->iir == 0) {
+            res |= 0x1;
+        }
+        return res;
+
+    case AUX_MU_LCR_REG:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_LCR_REG unsupported\n", __func__);
+        return 0;
+
+    case AUX_MU_MCR_REG:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_MCR_REG unsupported\n", __func__);
+        return 0;
+
+    case AUX_MU_LSR_REG:
+        res = 0x60; /* tx idle, empty */
+        if (s->read_count != 0) {
+            res |= 0x1;
+        }
+        return res;
+
+    case AUX_MU_MSR_REG:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_MSR_REG unsupported\n", __func__);
+        return 0;
+
+    case AUX_MU_SCRATCH:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_SCRATCH unsupported\n", __func__);
+        return 0;
+
+    case AUX_MU_CNTL_REG:
+        return 0x3; /* tx, rx enabled */
+
+    case AUX_MU_STAT_REG:
+        res = 0x30e; /* space in the output buffer, empty tx fifo, idle tx/rx */
+        if (s->read_count > 0) {
+            res |= 0x1; /* data in input buffer */
+            assert(s->read_count < BCM2835_AUX_RX_FIFO_LEN);
+            res |= ((uint32_t)s->read_count) << 16; /* rx fifo fill level */
+        }
+        return res;
+
+    case AUX_MU_BAUD_REG:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_BAUD_REG unsupported\n", __func__);
+        return 0;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                      __func__, offset);
+        return 0;
+    }
+}
+
+static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
+                              unsigned size)
+{
+    BCM2835AuxState *s = opaque;
+    unsigned char ch;
+
+    switch (offset) {
+    case AUX_ENABLES:
+        if (value != 1) {
+            qemu_log_mask(LOG_UNIMP, "%s: unsupported attempt to enable SPI "
+                          "or disable UART\n", __func__);
+        }
+        break;
+
+    case AUX_MU_IO_REG:
+        /* "DLAB bit set means access baudrate register" is NYI */
+        ch = value;
+        if (s->chr) {
+            qemu_chr_fe_write(s->chr, &ch, 1);
+        }
+        break;
+
+    case AUX_MU_IER_REG:
+        /* "DLAB bit set means access baudrate register" is NYI */
+        s->ier = value & (TX_INT | RX_INT);
+        bcm2835_aux_update(s);
+        break;
+
+    case AUX_MU_IIR_REG:
+        if (value & 0x2) {
+            s->read_count = 0;
+        }
+        break;
+
+    case AUX_MU_LCR_REG:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_LCR_REG unsupported\n", __func__);
+        break;
+
+    case AUX_MU_MCR_REG:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_MCR_REG unsupported\n", __func__);
+        break;
+
+    case AUX_MU_SCRATCH:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_SCRATCH unsupported\n", __func__);
+        break;
+
+    case AUX_MU_CNTL_REG:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_CNTL_REG unsupported\n", __func__);
+        break;
+
+    case AUX_MU_BAUD_REG:
+        qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_BAUD_REG unsupported\n", __func__);
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                      __func__, offset);
+    }
+
+    bcm2835_aux_update(s);
+}
+
+static int bcm2835_aux_can_receive(void *opaque)
+{
+    BCM2835AuxState *s = opaque;
+
+    return s->read_count < BCM2835_AUX_RX_FIFO_LEN;
+}
+
+static void bcm2835_aux_put_fifo(void *opaque, uint8_t value)
+{
+    BCM2835AuxState *s = opaque;
+    int slot;
+
+    slot = s->read_pos + s->read_count;
+    if (slot >= BCM2835_AUX_RX_FIFO_LEN) {
+        slot -= BCM2835_AUX_RX_FIFO_LEN;
+    }
+    s->read_fifo[slot] = value;
+    s->read_count++;
+    if (s->read_count == BCM2835_AUX_RX_FIFO_LEN) {
+        /* buffer full */
+    }
+    bcm2835_aux_update(s);
+}
+
+static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, int size)
+{
+    bcm2835_aux_put_fifo(opaque, *buf);
+}
+
+static const MemoryRegionOps bcm2835_aux_ops = {
+    .read = bcm2835_aux_read,
+    .write = bcm2835_aux_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static const VMStateDescription vmstate_bcm2835_aux = {
+    .name = TYPE_BCM2835_AUX,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8_ARRAY(read_fifo, BCM2835AuxState,
+                            BCM2835_AUX_RX_FIFO_LEN),
+        VMSTATE_UINT8(read_pos, BCM2835AuxState),
+        VMSTATE_UINT8(read_count, BCM2835AuxState),
+        VMSTATE_UINT8(ier, BCM2835AuxState),
+        VMSTATE_UINT8(iir, BCM2835AuxState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void bcm2835_aux_init(Object *obj)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    BCM2835AuxState *s = BCM2835_AUX(obj);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_aux_ops, s,
+                          TYPE_BCM2835_AUX, 0x100);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(sbd, &s->irq);
+}
+
+static void bcm2835_aux_realize(DeviceState *dev, Error **errp)
+{
+    BCM2835AuxState *s = BCM2835_AUX(dev);
+
+    if (s->chr) {
+        qemu_chr_add_handlers(s->chr, bcm2835_aux_can_receive,
+                              bcm2835_aux_receive, NULL, s);
+    }
+}
+
+static Property bcm2835_aux_props[] = {
+    DEFINE_PROP_CHR("chardev", BCM2835AuxState, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void bcm2835_aux_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = bcm2835_aux_realize;
+    dc->vmsd = &vmstate_bcm2835_aux;
+    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+    dc->props = bcm2835_aux_props;
+}
+
+static const TypeInfo bcm2835_aux_info = {
+    .name          = TYPE_BCM2835_AUX,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835AuxState),
+    .instance_init = bcm2835_aux_init,
+    .class_init    = bcm2835_aux_class_init,
+};
+
+static void bcm2835_aux_register_types(void)
+{
+    type_register_static(&bcm2835_aux_info);
+}
+
+type_init(bcm2835_aux_register_types)
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index 5d888dc..889adf5 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -14,6 +14,7 @@
 #include "qemu-common.h"
 #include "exec/address-spaces.h"
 #include "hw/sysbus.h"
+#include "hw/char/bcm2835_aux.h"
 #include "hw/intc/bcm2835_ic.h"
 #include "hw/misc/bcm2835_property.h"
 #include "hw/misc/bcm2835_mbox.h"
@@ -33,6 +34,7 @@ typedef struct BCM2835PeripheralState {
     qemu_irq irq, fiq;
 
     SysBusDevice *uart0;
+    BCM2835AuxState aux;
     BCM2835ICState ic;
     BCM2835PropertyState property;
     BCM2835MboxState mboxes;
diff --git a/include/hw/char/bcm2835_aux.h b/include/hw/char/bcm2835_aux.h
new file mode 100644
index 0000000..42f0ee7
--- /dev/null
+++ b/include/hw/char/bcm2835_aux.h
@@ -0,0 +1,33 @@
+/*
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_AUX_H
+#define BCM2835_AUX_H
+
+#include "hw/sysbus.h"
+#include "sysemu/char.h"
+
+#define TYPE_BCM2835_AUX "bcm2835-aux"
+#define BCM2835_AUX(obj) OBJECT_CHECK(BCM2835AuxState, (obj), TYPE_BCM2835_AUX)
+
+#define BCM2835_AUX_RX_FIFO_LEN 8
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    MemoryRegion iomem;
+    CharDriverState *chr;
+    qemu_irq irq;
+
+    uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN];
+    uint8_t read_pos, read_count;
+    uint8_t ier, iir;
+} BCM2835AuxState;
+
+#endif
-- 
1.9.1

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

* [Qemu-devel] [PULL 18/21] bcm2835_fb: add framebuffer device for Raspberry Pi
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (16 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 17/21] bcm2835_aux: add emulation of BCM2835 AUX (aka UART1) block Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 19/21] bcm2835_property: implement framebuffer control/configuration properties Peter Maydell
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Grégory ESTRADE <gregory.estrade@gmail.com>

The framebuffer occupies the upper portion of memory (64MiB by
default), but it can only be controlled/configured via a system
mailbox or property channel (to be added by a subsequent patch).

Signed-off-by: Grégory ESTRADE <gregory.estrade@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Message-id: 1457467526-8840-4-git-send-email-Andrew.Baumann@microsoft.com
[AB: added Windows (BGR) support and cleanup/refactoring for upstream submission]
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/bcm2835_peripherals.c         |  38 +++-
 hw/arm/bcm2836.c                     |   2 +
 hw/arm/raspi.c                       |   5 +-
 hw/display/Makefile.objs             |   1 +
 hw/display/bcm2835_fb.c              | 424 +++++++++++++++++++++++++++++++++++
 include/hw/arm/bcm2835_peripherals.h |   2 +
 include/hw/display/bcm2835_fb.h      |  47 ++++
 7 files changed, 517 insertions(+), 2 deletions(-)
 create mode 100644 hw/display/bcm2835_fb.c
 create mode 100644 include/hw/display/bcm2835_fb.h

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index d6453cc..c2fe6b7 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -62,6 +62,16 @@ static void bcm2835_peripherals_init(Object *obj)
     object_property_add_const_link(OBJECT(&s->mboxes), "mbox-mr",
                                    OBJECT(&s->mbox_mr), &error_abort);
 
+    /* Framebuffer */
+    object_initialize(&s->fb, sizeof(s->fb), TYPE_BCM2835_FB);
+    object_property_add_child(obj, "fb", OBJECT(&s->fb), NULL);
+    object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size",
+                              &error_abort);
+    qdev_set_parent_bus(DEVICE(&s->fb), sysbus_get_default());
+
+    object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
+                                   OBJECT(&s->gpu_bus_mr), &error_abort);
+
     /* Property channel */
     object_initialize(&s->property, sizeof(s->property), TYPE_BCM2835_PROPERTY);
     object_property_add_child(obj, "property", OBJECT(&s->property), NULL);
@@ -84,7 +94,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
     Object *obj;
     MemoryRegion *ram;
     Error *err = NULL;
-    uint32_t ram_size;
+    uint32_t ram_size, vcram_size;
     CharDriverState *chr;
     int n;
 
@@ -174,6 +184,32 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
         qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
                                INTERRUPT_ARM_MAILBOX));
 
+    /* Framebuffer */
+    vcram_size = (uint32_t)object_property_get_int(OBJECT(s), "vcram-size",
+                                                   &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    object_property_set_int(OBJECT(&s->fb), ram_size - vcram_size,
+                            "vcram-base", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    object_property_set_bool(OBJECT(&s->fb), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_FB << MBOX_AS_CHAN_SHIFT,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->fb), 0));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fb), 0,
+                       qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB));
+
     /* Property channel */
     object_property_set_int(OBJECT(&s->property), ram_size, "ram-size", &err);
     if (err) {
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
index 0321439..89a6b35 100644
--- a/hw/arm/bcm2836.c
+++ b/hw/arm/bcm2836.c
@@ -42,6 +42,8 @@ static void bcm2836_init(Object *obj)
                               &error_abort);
     object_property_add_alias(obj, "board-rev", OBJECT(&s->peripherals),
                               "board-rev", &error_abort);
+    object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
+                              "vcram-size", &error_abort);
     qdev_set_parent_bus(DEVICE(&s->peripherals), sysbus_get_default());
 }
 
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 6582279..5498209 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -113,6 +113,7 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
 static void raspi2_init(MachineState *machine)
 {
     RasPiState *s = g_new0(RasPiState, 1);
+    uint32_t vcram_size;
     DriveInfo *di;
     BlockBackend *blk;
     BusState *bus;
@@ -149,7 +150,9 @@ static void raspi2_init(MachineState *machine)
     qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
     object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal);
 
-    setup_boot(machine, 2, machine->ram_size);
+    vcram_size = object_property_get_int(OBJECT(&s->soc), "vcram-size",
+                                         &error_abort);
+    setup_boot(machine, 2, machine->ram_size - vcram_size);
 }
 
 static void raspi2_machine_init(MachineClass *mc)
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index f0cf431..d99780e 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -27,6 +27,7 @@ endif
 obj-$(CONFIG_OMAP) += omap_dss.o
 obj-$(CONFIG_OMAP) += omap_lcdc.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_lcd.o
+obj-$(CONFIG_RASPI) += bcm2835_fb.o
 obj-$(CONFIG_SM501) += sm501.o
 obj-$(CONFIG_TCX) += tcx.o
 obj-$(CONFIG_CG3) += cg3.o
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
new file mode 100644
index 0000000..779b56f
--- /dev/null
+++ b/hw/display/bcm2835_fb.c
@@ -0,0 +1,424 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Refactoring for Pi2 Copyright (c) 2015, Microsoft. Written by Andrew Baumann.
+ * This code is licensed under the GNU GPLv2 and later.
+ *
+ * Heavily based on milkymist-vgafb.c, copyright terms below:
+ *  QEMU model of the Milkymist VGA framebuffer.
+ *
+ *  Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/display/bcm2835_fb.h"
+#include "hw/display/framebuffer.h"
+#include "ui/pixel_ops.h"
+#include "hw/misc/bcm2835_mbox_defs.h"
+
+#define DEFAULT_VCRAM_SIZE 0x4000000
+#define BCM2835_FB_OFFSET  0x00100000
+
+static void fb_invalidate_display(void *opaque)
+{
+    BCM2835FBState *s = BCM2835_FB(opaque);
+
+    s->invalidate = true;
+}
+
+static void draw_line_src16(void *opaque, uint8_t *dst, const uint8_t *src,
+                            int width, int deststep)
+{
+    BCM2835FBState *s = opaque;
+    uint16_t rgb565;
+    uint32_t rgb888;
+    uint8_t r, g, b;
+    DisplaySurface *surface = qemu_console_surface(s->con);
+    int bpp = surface_bits_per_pixel(surface);
+
+    while (width--) {
+        switch (s->bpp) {
+        case 8:
+            /* lookup palette starting at video ram base
+             * TODO: cache translation, rather than doing this each time!
+             */
+            rgb888 = ldl_le_phys(&s->dma_as, s->vcram_base + (*src << 2));
+            r = (rgb888 >> 0) & 0xff;
+            g = (rgb888 >> 8) & 0xff;
+            b = (rgb888 >> 16) & 0xff;
+            src++;
+            break;
+        case 16:
+            rgb565 = lduw_le_p(src);
+            r = ((rgb565 >> 11) & 0x1f) << 3;
+            g = ((rgb565 >>  5) & 0x3f) << 2;
+            b = ((rgb565 >>  0) & 0x1f) << 3;
+            src += 2;
+            break;
+        case 24:
+            rgb888 = ldl_le_p(src);
+            r = (rgb888 >> 0) & 0xff;
+            g = (rgb888 >> 8) & 0xff;
+            b = (rgb888 >> 16) & 0xff;
+            src += 3;
+            break;
+        case 32:
+            rgb888 = ldl_le_p(src);
+            r = (rgb888 >> 0) & 0xff;
+            g = (rgb888 >> 8) & 0xff;
+            b = (rgb888 >> 16) & 0xff;
+            src += 4;
+            break;
+        default:
+            r = 0;
+            g = 0;
+            b = 0;
+            break;
+        }
+
+        if (s->pixo == 0) {
+            /* swap to BGR pixel format */
+            uint8_t tmp = r;
+            r = b;
+            b = tmp;
+        }
+
+        switch (bpp) {
+        case 8:
+            *dst++ = rgb_to_pixel8(r, g, b);
+            break;
+        case 15:
+            *(uint16_t *)dst = rgb_to_pixel15(r, g, b);
+            dst += 2;
+            break;
+        case 16:
+            *(uint16_t *)dst = rgb_to_pixel16(r, g, b);
+            dst += 2;
+            break;
+        case 24:
+            rgb888 = rgb_to_pixel24(r, g, b);
+            *dst++ = rgb888 & 0xff;
+            *dst++ = (rgb888 >> 8) & 0xff;
+            *dst++ = (rgb888 >> 16) & 0xff;
+            break;
+        case 32:
+            *(uint32_t *)dst = rgb_to_pixel32(r, g, b);
+            dst += 4;
+            break;
+        default:
+            return;
+        }
+    }
+}
+
+static void fb_update_display(void *opaque)
+{
+    BCM2835FBState *s = opaque;
+    DisplaySurface *surface = qemu_console_surface(s->con);
+    int first = 0;
+    int last = 0;
+    int src_width = 0;
+    int dest_width = 0;
+
+    if (s->lock || !s->xres) {
+        return;
+    }
+
+    src_width = s->xres * (s->bpp >> 3);
+    dest_width = s->xres;
+
+    switch (surface_bits_per_pixel(surface)) {
+    case 0:
+        return;
+    case 8:
+        break;
+    case 15:
+        dest_width *= 2;
+        break;
+    case 16:
+        dest_width *= 2;
+        break;
+    case 24:
+        dest_width *= 3;
+        break;
+    case 32:
+        dest_width *= 4;
+        break;
+    default:
+        hw_error("bcm2835_fb: bad color depth\n");
+        break;
+    }
+
+    if (s->invalidate) {
+        framebuffer_update_memory_section(&s->fbsection, s->dma_mr, s->base,
+                                          s->yres, src_width);
+    }
+
+    framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
+                               src_width, dest_width, 0, s->invalidate,
+                               draw_line_src16, s, &first, &last);
+
+    if (first >= 0) {
+        dpy_gfx_update(s->con, 0, first, s->xres, last - first + 1);
+    }
+
+    s->invalidate = false;
+}
+
+static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
+{
+    value &= ~0xf;
+
+    s->lock = true;
+
+    s->xres = ldl_le_phys(&s->dma_as, value);
+    s->yres = ldl_le_phys(&s->dma_as, value + 4);
+    s->xres_virtual = ldl_le_phys(&s->dma_as, value + 8);
+    s->yres_virtual = ldl_le_phys(&s->dma_as, value + 12);
+    s->bpp = ldl_le_phys(&s->dma_as, value + 20);
+    s->xoffset = ldl_le_phys(&s->dma_as, value + 24);
+    s->yoffset = ldl_le_phys(&s->dma_as, value + 28);
+
+    s->base = s->vcram_base | (value & 0xc0000000);
+    s->base += BCM2835_FB_OFFSET;
+
+    /* TODO - Manage properly virtual resolution */
+
+    s->pitch = s->xres * (s->bpp >> 3);
+    s->size = s->yres * s->pitch;
+
+    stl_le_phys(&s->dma_as, value + 16, s->pitch);
+    stl_le_phys(&s->dma_as, value + 32, s->base);
+    stl_le_phys(&s->dma_as, value + 36, s->size);
+
+    s->invalidate = true;
+    qemu_console_resize(s->con, s->xres, s->yres);
+    s->lock = false;
+}
+
+void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres,
+                            uint32_t *xoffset, uint32_t *yoffset, uint32_t *bpp,
+                            uint32_t *pixo, uint32_t *alpha)
+{
+    s->lock = true;
+
+    /* TODO: input validation! */
+    if (xres) {
+        s->xres = *xres;
+    }
+    if (yres) {
+        s->yres = *yres;
+    }
+    if (xoffset) {
+        s->xoffset = *xoffset;
+    }
+    if (yoffset) {
+        s->yoffset = *yoffset;
+    }
+    if (bpp) {
+        s->bpp = *bpp;
+    }
+    if (pixo) {
+        s->pixo = *pixo;
+    }
+    if (alpha) {
+        s->alpha = *alpha;
+    }
+
+    /* TODO - Manage properly virtual resolution */
+
+    s->pitch = s->xres * (s->bpp >> 3);
+    s->size = s->yres * s->pitch;
+
+    s->invalidate = true;
+    qemu_console_resize(s->con, s->xres, s->yres);
+    s->lock = false;
+}
+
+static uint64_t bcm2835_fb_read(void *opaque, hwaddr offset, unsigned size)
+{
+    BCM2835FBState *s = opaque;
+    uint32_t res = 0;
+
+    switch (offset) {
+    case MBOX_AS_DATA:
+        res = MBOX_CHAN_FB;
+        s->pending = false;
+        qemu_set_irq(s->mbox_irq, 0);
+        break;
+
+    case MBOX_AS_PENDING:
+        res = s->pending;
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                      __func__, offset);
+        return 0;
+    }
+
+    return res;
+}
+
+static void bcm2835_fb_write(void *opaque, hwaddr offset, uint64_t value,
+                             unsigned size)
+{
+    BCM2835FBState *s = opaque;
+
+    switch (offset) {
+    case MBOX_AS_DATA:
+        /* bcm2835_mbox should check our pending status before pushing */
+        assert(!s->pending);
+        s->pending = true;
+        bcm2835_fb_mbox_push(s, value);
+        qemu_set_irq(s->mbox_irq, 1);
+        break;
+
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                      __func__, offset);
+        return;
+    }
+}
+
+static const MemoryRegionOps bcm2835_fb_ops = {
+    .read = bcm2835_fb_read,
+    .write = bcm2835_fb_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static const VMStateDescription vmstate_bcm2835_fb = {
+    .name = TYPE_BCM2835_FB,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_BOOL(lock, BCM2835FBState),
+        VMSTATE_BOOL(invalidate, BCM2835FBState),
+        VMSTATE_BOOL(pending, BCM2835FBState),
+        VMSTATE_UINT32(xres, BCM2835FBState),
+        VMSTATE_UINT32(yres, BCM2835FBState),
+        VMSTATE_UINT32(xres_virtual, BCM2835FBState),
+        VMSTATE_UINT32(yres_virtual, BCM2835FBState),
+        VMSTATE_UINT32(xoffset, BCM2835FBState),
+        VMSTATE_UINT32(yoffset, BCM2835FBState),
+        VMSTATE_UINT32(bpp, BCM2835FBState),
+        VMSTATE_UINT32(base, BCM2835FBState),
+        VMSTATE_UINT32(pitch, BCM2835FBState),
+        VMSTATE_UINT32(size, BCM2835FBState),
+        VMSTATE_UINT32(pixo, BCM2835FBState),
+        VMSTATE_UINT32(alpha, BCM2835FBState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const GraphicHwOps vgafb_ops = {
+    .invalidate  = fb_invalidate_display,
+    .gfx_update  = fb_update_display,
+};
+
+static void bcm2835_fb_init(Object *obj)
+{
+    BCM2835FBState *s = BCM2835_FB(obj);
+
+    memory_region_init_io(&s->iomem, obj, &bcm2835_fb_ops, s, TYPE_BCM2835_FB,
+                          0x10);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+    sysbus_init_irq(SYS_BUS_DEVICE(s), &s->mbox_irq);
+}
+
+static void bcm2835_fb_reset(DeviceState *dev)
+{
+    BCM2835FBState *s = BCM2835_FB(dev);
+
+    s->pending = false;
+
+    s->xres_virtual = s->xres;
+    s->yres_virtual = s->yres;
+    s->xoffset = 0;
+    s->yoffset = 0;
+    s->base = s->vcram_base + BCM2835_FB_OFFSET;
+    s->pitch = s->xres * (s->bpp >> 3);
+    s->size = s->yres * s->pitch;
+
+    s->invalidate = true;
+    s->lock = false;
+}
+
+static void bcm2835_fb_realize(DeviceState *dev, Error **errp)
+{
+    BCM2835FBState *s = BCM2835_FB(dev);
+    Error *err = NULL;
+    Object *obj;
+
+    if (s->vcram_base == 0) {
+        error_setg(errp, "%s: required vcram-base property not set", __func__);
+        return;
+    }
+
+    obj = object_property_get_link(OBJECT(dev), "dma-mr", &err);
+    if (obj == NULL) {
+        error_setg(errp, "%s: required dma-mr link not found: %s",
+                   __func__, error_get_pretty(err));
+        return;
+    }
+
+    s->dma_mr = MEMORY_REGION(obj);
+    address_space_init(&s->dma_as, s->dma_mr, NULL);
+
+    bcm2835_fb_reset(dev);
+
+    s->con = graphic_console_init(dev, 0, &vgafb_ops, s);
+    qemu_console_resize(s->con, s->xres, s->yres);
+}
+
+static Property bcm2835_fb_props[] = {
+    DEFINE_PROP_UINT32("vcram-base", BCM2835FBState, vcram_base, 0),/*required*/
+    DEFINE_PROP_UINT32("vcram-size", BCM2835FBState, vcram_size,
+                       DEFAULT_VCRAM_SIZE),
+    DEFINE_PROP_UINT32("xres", BCM2835FBState, xres, 640),
+    DEFINE_PROP_UINT32("yres", BCM2835FBState, yres, 480),
+    DEFINE_PROP_UINT32("bpp", BCM2835FBState, bpp, 16),
+    DEFINE_PROP_UINT32("pixo", BCM2835FBState, pixo, 1), /* 1=RGB, 0=BGR */
+    DEFINE_PROP_UINT32("alpha", BCM2835FBState, alpha, 2), /* alpha ignored */
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void bcm2835_fb_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->props = bcm2835_fb_props;
+    dc->realize = bcm2835_fb_realize;
+    dc->reset = bcm2835_fb_reset;
+    dc->vmsd = &vmstate_bcm2835_fb;
+}
+
+static TypeInfo bcm2835_fb_info = {
+    .name          = TYPE_BCM2835_FB,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835FBState),
+    .class_init    = bcm2835_fb_class_init,
+    .instance_init = bcm2835_fb_init,
+};
+
+static void bcm2835_fb_register_types(void)
+{
+    type_register_static(&bcm2835_fb_info);
+}
+
+type_init(bcm2835_fb_register_types)
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index 889adf5..e19d360 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -15,6 +15,7 @@
 #include "exec/address-spaces.h"
 #include "hw/sysbus.h"
 #include "hw/char/bcm2835_aux.h"
+#include "hw/display/bcm2835_fb.h"
 #include "hw/intc/bcm2835_ic.h"
 #include "hw/misc/bcm2835_property.h"
 #include "hw/misc/bcm2835_mbox.h"
@@ -35,6 +36,7 @@ typedef struct BCM2835PeripheralState {
 
     SysBusDevice *uart0;
     BCM2835AuxState aux;
+    BCM2835FBState fb;
     BCM2835ICState ic;
     BCM2835PropertyState property;
     BCM2835MboxState mboxes;
diff --git a/include/hw/display/bcm2835_fb.h b/include/hw/display/bcm2835_fb.h
new file mode 100644
index 0000000..9a12d7a
--- /dev/null
+++ b/include/hw/display/bcm2835_fb.h
@@ -0,0 +1,47 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_FB_H
+#define BCM2835_FB_H
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "ui/console.h"
+
+#define TYPE_BCM2835_FB "bcm2835-fb"
+#define BCM2835_FB(obj) OBJECT_CHECK(BCM2835FBState, (obj), TYPE_BCM2835_FB)
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice busdev;
+    /*< public >*/
+
+    uint32_t vcram_base, vcram_size;
+    MemoryRegion *dma_mr;
+    AddressSpace dma_as;
+    MemoryRegion iomem;
+    MemoryRegionSection fbsection;
+    QemuConsole *con;
+    qemu_irq mbox_irq;
+
+    bool lock, invalidate, pending;
+    uint32_t xres, yres;
+    uint32_t xres_virtual, yres_virtual;
+    uint32_t xoffset, yoffset;
+    uint32_t bpp;
+    uint32_t base, pitch, size;
+    uint32_t pixo, alpha;
+} BCM2835FBState;
+
+void bcm2835_fb_reconfigure(BCM2835FBState *s, uint32_t *xres, uint32_t *yres,
+                            uint32_t *xoffset, uint32_t *yoffset, uint32_t *bpp,
+                            uint32_t *pixo, uint32_t *alpha);
+
+#endif
-- 
1.9.1

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

* [Qemu-devel] [PULL 19/21] bcm2835_property: implement framebuffer control/configuration properties
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (17 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 18/21] bcm2835_fb: add framebuffer device for Raspberry Pi Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 20/21] bcm2835_dma: add emulation of Raspberry Pi DMA controller Peter Maydell
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Grégory ESTRADE <gregory.estrade@gmail.com>

The property channel driver now interfaces with the framebuffer device
to query and set framebuffer parameters. As a result of this, the "get
ARM RAM size" query now correctly returns the video RAM base address
(not total RAM size), and the ram-size property is no longer relevant
here.

Signed-off-by: Grégory ESTRADE <gregory.estrade@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Message-id: 1457467526-8840-5-git-send-email-Andrew.Baumann@microsoft.com
[AB: cleanup/refactoring for upstream submission]
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/bcm2835_peripherals.c       |   8 +--
 hw/arm/raspi.c                     |   7 +-
 hw/misc/bcm2835_property.c         | 139 ++++++++++++++++++++++++++++++++++++-
 include/hw/misc/bcm2835_property.h |   5 +-
 4 files changed, 144 insertions(+), 15 deletions(-)

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index c2fe6b7..4d74a18 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -79,6 +79,8 @@ static void bcm2835_peripherals_init(Object *obj)
                               "board-rev", &error_abort);
     qdev_set_parent_bus(DEVICE(&s->property), sysbus_get_default());
 
+    object_property_add_const_link(OBJECT(&s->property), "fb",
+                                   OBJECT(&s->fb), &error_abort);
     object_property_add_const_link(OBJECT(&s->property), "dma-mr",
                                    OBJECT(&s->gpu_bus_mr), &error_abort);
 
@@ -211,12 +213,6 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
                        qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB));
 
     /* Property channel */
-    object_property_set_int(OBJECT(&s->property), ram_size, "ram-size", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-
     object_property_set_bool(OBJECT(&s->property), true, "realized", &err);
     if (err) {
         error_propagate(errp, err);
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 5498209..83fe809 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -164,11 +164,6 @@ static void raspi2_machine_init(MachineClass *mc)
     mc->no_floppy = 1;
     mc->no_cdrom = 1;
     mc->max_cpus = BCM2836_NCPUS;
-
-    /* XXX: Temporary restriction in RAM size from the full 1GB. Since
-     * we do not yet support the framebuffer / GPU, we need to limit
-     * RAM usable by the OS to sit below the peripherals.
-     */
-    mc->default_ram_size = 0x3F000000; /* BCM2836_PERI_BASE */
+    mc->default_ram_size = 1024 * 1024 * 1024;
 };
 DEFINE_MACHINE("raspi2", raspi2_machine_init)
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index 41fbbe3..15dcc02 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -17,6 +17,11 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
     uint32_t tot_len;
     size_t resplen;
     uint32_t tmp;
+    int n;
+    uint32_t offset, length, color;
+    uint32_t xres, yres, xoffset, yoffset, bpp, pixo, alpha;
+    uint32_t *newxres = NULL, *newyres = NULL, *newxoffset = NULL,
+        *newyoffset = NULL, *newbpp = NULL, *newpixo = NULL, *newalpha = NULL;
 
     value &= ~0xf;
 
@@ -60,7 +65,14 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
             /* base */
             stl_le_phys(&s->dma_as, value + 12, 0);
             /* size */
-            stl_le_phys(&s->dma_as, value + 16, s->ram_size);
+            stl_le_phys(&s->dma_as, value + 16, s->fbdev->vcram_base);
+            resplen = 8;
+            break;
+        case 0x00010006: /* Get VC memory */
+            /* base */
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->vcram_base);
+            /* size */
+            stl_le_phys(&s->dma_as, value + 16, s->fbdev->vcram_size);
             resplen = 8;
             break;
         case 0x00028001: /* Set power state */
@@ -122,6 +134,114 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
             resplen = 8;
             break;
 
+        /* Frame buffer */
+
+        case 0x00040001: /* Allocate buffer */
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->base);
+            stl_le_phys(&s->dma_as, value + 16, s->fbdev->size);
+            resplen = 8;
+            break;
+        case 0x00048001: /* Release buffer */
+            resplen = 0;
+            break;
+        case 0x00040002: /* Blank screen */
+            resplen = 4;
+            break;
+        case 0x00040003: /* Get display width/height */
+        case 0x00040004:
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->xres);
+            stl_le_phys(&s->dma_as, value + 16, s->fbdev->yres);
+            resplen = 8;
+            break;
+        case 0x00044003: /* Test display width/height */
+        case 0x00044004:
+            resplen = 8;
+            break;
+        case 0x00048003: /* Set display width/height */
+        case 0x00048004:
+            xres = ldl_le_phys(&s->dma_as, value + 12);
+            newxres = &xres;
+            yres = ldl_le_phys(&s->dma_as, value + 16);
+            newyres = &yres;
+            resplen = 8;
+            break;
+        case 0x00040005: /* Get depth */
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->bpp);
+            resplen = 4;
+            break;
+        case 0x00044005: /* Test depth */
+            resplen = 4;
+            break;
+        case 0x00048005: /* Set depth */
+            bpp = ldl_le_phys(&s->dma_as, value + 12);
+            newbpp = &bpp;
+            resplen = 4;
+            break;
+        case 0x00040006: /* Get pixel order */
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->pixo);
+            resplen = 4;
+            break;
+        case 0x00044006: /* Test pixel order */
+            resplen = 4;
+            break;
+        case 0x00048006: /* Set pixel order */
+            pixo = ldl_le_phys(&s->dma_as, value + 12);
+            newpixo = &pixo;
+            resplen = 4;
+            break;
+        case 0x00040007: /* Get alpha */
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->alpha);
+            resplen = 4;
+            break;
+        case 0x00044007: /* Test pixel alpha */
+            resplen = 4;
+            break;
+        case 0x00048007: /* Set alpha */
+            alpha = ldl_le_phys(&s->dma_as, value + 12);
+            newalpha = &alpha;
+            resplen = 4;
+            break;
+        case 0x00040008: /* Get pitch */
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->pitch);
+            resplen = 4;
+            break;
+        case 0x00040009: /* Get virtual offset */
+            stl_le_phys(&s->dma_as, value + 12, s->fbdev->xoffset);
+            stl_le_phys(&s->dma_as, value + 16, s->fbdev->yoffset);
+            resplen = 8;
+            break;
+        case 0x00044009: /* Test virtual offset */
+            resplen = 8;
+            break;
+        case 0x00048009: /* Set virtual offset */
+            xoffset = ldl_le_phys(&s->dma_as, value + 12);
+            newxoffset = &xoffset;
+            yoffset = ldl_le_phys(&s->dma_as, value + 16);
+            newyoffset = &yoffset;
+            resplen = 8;
+            break;
+        case 0x0004000a: /* Get/Test/Set overscan */
+        case 0x0004400a:
+        case 0x0004800a:
+            stl_le_phys(&s->dma_as, value + 12, 0);
+            stl_le_phys(&s->dma_as, value + 16, 0);
+            stl_le_phys(&s->dma_as, value + 20, 0);
+            stl_le_phys(&s->dma_as, value + 24, 0);
+            resplen = 16;
+            break;
+        case 0x0004800b: /* Set palette */
+            offset = ldl_le_phys(&s->dma_as, value + 12);
+            length = ldl_le_phys(&s->dma_as, value + 16);
+            n = 0;
+            while (n < length - offset) {
+                color = ldl_le_phys(&s->dma_as, value + 20 + (n << 2));
+                stl_le_phys(&s->dma_as,
+                            s->fbdev->vcram_base + ((offset + n) << 2), color);
+                n++;
+            }
+            stl_le_phys(&s->dma_as, value + 12, 0);
+            resplen = 4;
+            break;
 
         case 0x00060001: /* Get DMA channels */
             /* channels 2-5 */
@@ -147,6 +267,13 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
         value += bufsize + 12;
     }
 
+    /* Reconfigure framebuffer if required */
+    if (newxres || newyres || newxoffset || newyoffset || newbpp || newpixo
+        || newalpha) {
+        bcm2835_fb_reconfigure(s->fbdev, newxres, newyres, newxoffset,
+                               newyoffset, newbpp, newpixo, newalpha);
+    }
+
     /* Buffer response code */
     stl_le_phys(&s->dma_as, s->addr + 4, (1 << 31));
 }
@@ -241,6 +368,15 @@ static void bcm2835_property_realize(DeviceState *dev, Error **errp)
     Object *obj;
     Error *err = NULL;
 
+    obj = object_property_get_link(OBJECT(dev), "fb", &err);
+    if (obj == NULL) {
+        error_setg(errp, "%s: required fb link not found: %s",
+                   __func__, error_get_pretty(err));
+        return;
+    }
+
+    s->fbdev = BCM2835_FB(obj);
+
     obj = object_property_get_link(OBJECT(dev), "dma-mr", &err);
     if (obj == NULL) {
         error_setg(errp, "%s: required dma-mr link not found: %s",
@@ -259,7 +395,6 @@ static void bcm2835_property_realize(DeviceState *dev, Error **errp)
 
 static Property bcm2835_property_props[] = {
     DEFINE_PROP_UINT32("board-rev", BCM2835PropertyState, board_rev, 0),
-    DEFINE_PROP_UINT32("ram-size", BCM2835PropertyState, ram_size, 0),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/include/hw/misc/bcm2835_property.h b/include/hw/misc/bcm2835_property.h
index df889ea..edcab60 100644
--- a/include/hw/misc/bcm2835_property.h
+++ b/include/hw/misc/bcm2835_property.h
@@ -9,6 +9,7 @@
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "net/net.h"
+#include "hw/display/bcm2835_fb.h"
 
 #define TYPE_BCM2835_PROPERTY "bcm2835-property"
 #define BCM2835_PROPERTY(obj) \
@@ -18,13 +19,15 @@ typedef struct {
     /*< private >*/
     SysBusDevice busdev;
     /*< public >*/
+
     MemoryRegion *dma_mr;
     AddressSpace dma_as;
     MemoryRegion iomem;
     qemu_irq mbox_irq;
+    BCM2835FBState *fbdev;
+
     MACAddr macaddr;
     uint32_t board_rev;
-    uint32_t ram_size;
     uint32_t addr;
     bool pending;
 } BCM2835PropertyState;
-- 
1.9.1

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

* [Qemu-devel] [PULL 20/21] bcm2835_dma: add emulation of Raspberry Pi DMA controller
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (18 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 19/21] bcm2835_property: implement framebuffer control/configuration properties Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:18 ` [Qemu-devel] [PULL 21/21] sd: Fix "info qtree" on boards with SD cards Peter Maydell
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

From: Grégory ESTRADE <gregory.estrade@gmail.com>

At present, all DMA transfers complete inline (so a looping descriptor
queue will lock up the device). We also do not model pause/abort,
arbitrarion/priority, or debug features.

Signed-off-by: Grégory ESTRADE <gregory.estrade@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Message-id: 1457467526-8840-6-git-send-email-Andrew.Baumann@microsoft.com
[AB: implement 2D mode, cleanup/refactoring for upstream submission]
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/bcm2835_peripherals.c         |  26 +++
 hw/dma/Makefile.objs                 |   1 +
 hw/dma/bcm2835_dma.c                 | 408 +++++++++++++++++++++++++++++++++++
 include/hw/arm/bcm2835_peripherals.h |   2 +
 include/hw/dma/bcm2835_dma.h         |  47 ++++
 5 files changed, 484 insertions(+)
 create mode 100644 hw/dma/bcm2835_dma.c
 create mode 100644 include/hw/dma/bcm2835_dma.h

diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 4d74a18..8099a8a 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -88,6 +88,14 @@ static void bcm2835_peripherals_init(Object *obj)
     object_initialize(&s->sdhci, sizeof(s->sdhci), TYPE_SYSBUS_SDHCI);
     object_property_add_child(obj, "sdhci", OBJECT(&s->sdhci), NULL);
     qdev_set_parent_bus(DEVICE(&s->sdhci), sysbus_get_default());
+
+    /* DMA Channels */
+    object_initialize(&s->dma, sizeof(s->dma), TYPE_BCM2835_DMA);
+    object_property_add_child(obj, "dma", OBJECT(&s->dma), NULL);
+    qdev_set_parent_bus(DEVICE(&s->dma), sysbus_get_default());
+
+    object_property_add_const_link(OBJECT(&s->dma), "dma-mr",
+                                   OBJECT(&s->gpu_bus_mr), &error_abort);
 }
 
 static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
@@ -258,6 +266,24 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    /* DMA Channels */
+    object_property_set_bool(OBJECT(&s->dma), true, "realized", &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    memory_region_add_subregion(&s->peri_mr, DMA_OFFSET,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 0));
+    memory_region_add_subregion(&s->peri_mr, DMA15_OFFSET,
+                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 1));
+
+    for (n = 0; n <= 12; n++) {
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), n,
+                           qdev_get_gpio_in_named(DEVICE(&s->ic),
+                                                  BCM2835_IC_GPU_IRQ,
+                                                  INTERRUPT_DMA0 + n));
+    }
 }
 
 static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
index 0e65ed0..a1abbcf 100644
--- a/hw/dma/Makefile.objs
+++ b/hw/dma/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-$(CONFIG_SUN4M) += sun4m_iommu.o
 
 obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
 obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
+obj-$(CONFIG_RASPI) += bcm2835_dma.o
diff --git a/hw/dma/bcm2835_dma.c b/hw/dma/bcm2835_dma.c
new file mode 100644
index 0000000..c7ce4e4
--- /dev/null
+++ b/hw/dma/bcm2835_dma.c
@@ -0,0 +1,408 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/dma/bcm2835_dma.h"
+
+/* DMA CS Control and Status bits */
+#define BCM2708_DMA_ACTIVE      (1 << 0)
+#define BCM2708_DMA_END         (1 << 1) /* GE */
+#define BCM2708_DMA_INT         (1 << 2)
+#define BCM2708_DMA_ISPAUSED    (1 << 4)  /* Pause requested or not active */
+#define BCM2708_DMA_ISHELD      (1 << 5)  /* Is held by DREQ flow control */
+#define BCM2708_DMA_ERR         (1 << 8)
+#define BCM2708_DMA_ABORT       (1 << 30) /* stop current CB, go to next, WO */
+#define BCM2708_DMA_RESET       (1 << 31) /* WO, self clearing */
+
+/* DMA control block "info" field bits */
+#define BCM2708_DMA_INT_EN      (1 << 0)
+#define BCM2708_DMA_TDMODE      (1 << 1)
+#define BCM2708_DMA_WAIT_RESP   (1 << 3)
+#define BCM2708_DMA_D_INC       (1 << 4)
+#define BCM2708_DMA_D_WIDTH     (1 << 5)
+#define BCM2708_DMA_D_DREQ      (1 << 6)
+#define BCM2708_DMA_D_IGNORE    (1 << 7)
+#define BCM2708_DMA_S_INC       (1 << 8)
+#define BCM2708_DMA_S_WIDTH     (1 << 9)
+#define BCM2708_DMA_S_DREQ      (1 << 10)
+#define BCM2708_DMA_S_IGNORE    (1 << 11)
+
+/* Register offsets */
+#define BCM2708_DMA_CS          0x00 /* Control and Status */
+#define BCM2708_DMA_ADDR        0x04 /* Control block address */
+/* the current control block appears in the following registers - read only */
+#define BCM2708_DMA_INFO        0x08
+#define BCM2708_DMA_SOURCE_AD   0x0c
+#define BCM2708_DMA_DEST_AD     0x10
+#define BCM2708_DMA_TXFR_LEN    0x14
+#define BCM2708_DMA_STRIDE      0x18
+#define BCM2708_DMA_NEXTCB      0x1C
+#define BCM2708_DMA_DEBUG       0x20
+
+#define BCM2708_DMA_INT_STATUS  0xfe0 /* Interrupt status of each channel */
+#define BCM2708_DMA_ENABLE      0xff0 /* Global enable bits for each channel */
+
+#define BCM2708_DMA_CS_RW_MASK  0x30ff0001 /* All RW bits in DMA_CS */
+
+static void bcm2835_dma_update(BCM2835DMAState *s, unsigned c)
+{
+    BCM2835DMAChan *ch = &s->chan[c];
+    uint32_t data, xlen, ylen;
+    int16_t dst_stride, src_stride;
+
+    if (!(s->enable & (1 << c))) {
+        return;
+    }
+
+    while ((s->enable & (1 << c)) && (ch->conblk_ad != 0)) {
+        /* CB fetch */
+        ch->ti = ldl_le_phys(&s->dma_as, ch->conblk_ad);
+        ch->source_ad = ldl_le_phys(&s->dma_as, ch->conblk_ad + 4);
+        ch->dest_ad = ldl_le_phys(&s->dma_as, ch->conblk_ad + 8);
+        ch->txfr_len = ldl_le_phys(&s->dma_as, ch->conblk_ad + 12);
+        ch->stride = ldl_le_phys(&s->dma_as, ch->conblk_ad + 16);
+        ch->nextconbk = ldl_le_phys(&s->dma_as, ch->conblk_ad + 20);
+
+        if (ch->ti & BCM2708_DMA_TDMODE) {
+            /* 2D transfer mode */
+            ylen = (ch->txfr_len >> 16) & 0x3fff;
+            xlen = ch->txfr_len & 0xffff;
+            dst_stride = ch->stride >> 16;
+            src_stride = ch->stride & 0xffff;
+        } else {
+            ylen = 1;
+            xlen = ch->txfr_len;
+            dst_stride = 0;
+            src_stride = 0;
+        }
+
+        while (ylen != 0) {
+            /* Normal transfer mode */
+            while (xlen != 0) {
+                if (ch->ti & BCM2708_DMA_S_IGNORE) {
+                    /* Ignore reads */
+                    data = 0;
+                } else {
+                    data = ldl_le_phys(&s->dma_as, ch->source_ad);
+                }
+                if (ch->ti & BCM2708_DMA_S_INC) {
+                    ch->source_ad += 4;
+                }
+
+                if (ch->ti & BCM2708_DMA_D_IGNORE) {
+                    /* Ignore writes */
+                } else {
+                    stl_le_phys(&s->dma_as, ch->dest_ad, data);
+                }
+                if (ch->ti & BCM2708_DMA_D_INC) {
+                    ch->dest_ad += 4;
+                }
+
+                /* update remaining transfer length */
+                xlen -= 4;
+                if (ch->ti & BCM2708_DMA_TDMODE) {
+                    ch->txfr_len = (ylen << 16) | xlen;
+                } else {
+                    ch->txfr_len = xlen;
+                }
+            }
+
+            if (--ylen != 0) {
+                ch->source_ad += src_stride;
+                ch->dest_ad += dst_stride;
+            }
+        }
+        ch->cs |= BCM2708_DMA_END;
+        if (ch->ti & BCM2708_DMA_INT_EN) {
+            ch->cs |= BCM2708_DMA_INT;
+            s->int_status |= (1 << c);
+            qemu_set_irq(ch->irq, 1);
+        }
+
+        /* Process next CB */
+        ch->conblk_ad = ch->nextconbk;
+    }
+
+    ch->cs &= ~BCM2708_DMA_ACTIVE;
+    ch->cs |= BCM2708_DMA_ISPAUSED;
+}
+
+static void bcm2835_dma_chan_reset(BCM2835DMAChan *ch)
+{
+    ch->cs = 0;
+    ch->conblk_ad = 0;
+}
+
+static uint64_t bcm2835_dma_read(BCM2835DMAState *s, hwaddr offset,
+                                 unsigned size, unsigned c)
+{
+    BCM2835DMAChan *ch;
+    uint32_t res = 0;
+
+    assert(size == 4);
+    assert(c < BCM2835_DMA_NCHANS);
+
+    ch = &s->chan[c];
+
+    switch (offset) {
+    case BCM2708_DMA_CS:
+        res = ch->cs;
+        break;
+    case BCM2708_DMA_ADDR:
+        res = ch->conblk_ad;
+        break;
+    case BCM2708_DMA_INFO:
+        res = ch->ti;
+        break;
+    case BCM2708_DMA_SOURCE_AD:
+        res = ch->source_ad;
+        break;
+    case BCM2708_DMA_DEST_AD:
+        res = ch->dest_ad;
+        break;
+    case BCM2708_DMA_TXFR_LEN:
+        res = ch->txfr_len;
+        break;
+    case BCM2708_DMA_STRIDE:
+        res = ch->stride;
+        break;
+    case BCM2708_DMA_NEXTCB:
+        res = ch->nextconbk;
+        break;
+    case BCM2708_DMA_DEBUG:
+        res = ch->debug;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                      __func__, offset);
+        break;
+    }
+    return res;
+}
+
+static void bcm2835_dma_write(BCM2835DMAState *s, hwaddr offset,
+                              uint64_t value, unsigned size, unsigned c)
+{
+    BCM2835DMAChan *ch;
+    uint32_t oldcs;
+
+    assert(size == 4);
+    assert(c < BCM2835_DMA_NCHANS);
+
+    ch = &s->chan[c];
+
+    switch (offset) {
+    case BCM2708_DMA_CS:
+        oldcs = ch->cs;
+        if (value & BCM2708_DMA_RESET) {
+            bcm2835_dma_chan_reset(ch);
+        }
+        if (value & BCM2708_DMA_ABORT) {
+            /* abort is a no-op, since we always run to completion */
+        }
+        if (value & BCM2708_DMA_END) {
+            ch->cs &= ~BCM2708_DMA_END;
+        }
+        if (value & BCM2708_DMA_INT) {
+            ch->cs &= ~BCM2708_DMA_INT;
+            s->int_status &= ~(1 << c);
+            qemu_set_irq(ch->irq, 0);
+        }
+        ch->cs &= ~BCM2708_DMA_CS_RW_MASK;
+        ch->cs |= (value & BCM2708_DMA_CS_RW_MASK);
+        if (!(oldcs & BCM2708_DMA_ACTIVE) && (ch->cs & BCM2708_DMA_ACTIVE)) {
+            bcm2835_dma_update(s, c);
+        }
+        break;
+    case BCM2708_DMA_ADDR:
+        ch->conblk_ad = value;
+        break;
+    case BCM2708_DMA_DEBUG:
+        ch->debug = value;
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                      __func__, offset);
+        break;
+    }
+}
+
+static uint64_t bcm2835_dma0_read(void *opaque, hwaddr offset, unsigned size)
+{
+    BCM2835DMAState *s = opaque;
+
+    if (offset < 0xf00) {
+        return bcm2835_dma_read(s, (offset & 0xff), size, (offset >> 8) & 0xf);
+    } else {
+        switch (offset) {
+        case BCM2708_DMA_INT_STATUS:
+            return s->int_status;
+        case BCM2708_DMA_ENABLE:
+            return s->enable;
+        default:
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                          __func__, offset);
+            return 0;
+        }
+    }
+}
+
+static uint64_t bcm2835_dma15_read(void *opaque, hwaddr offset, unsigned size)
+{
+    return bcm2835_dma_read(opaque, (offset & 0xff), size, 15);
+}
+
+static void bcm2835_dma0_write(void *opaque, hwaddr offset, uint64_t value,
+                               unsigned size)
+{
+    BCM2835DMAState *s = opaque;
+
+    if (offset < 0xf00) {
+        bcm2835_dma_write(s, (offset & 0xff), value, size, (offset >> 8) & 0xf);
+    } else {
+        switch (offset) {
+        case BCM2708_DMA_INT_STATUS:
+            break;
+        case BCM2708_DMA_ENABLE:
+            s->enable = (value & 0xffff);
+            break;
+        default:
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+                          __func__, offset);
+        }
+    }
+
+}
+
+static void bcm2835_dma15_write(void *opaque, hwaddr offset, uint64_t value,
+                                unsigned size)
+{
+    bcm2835_dma_write(opaque, (offset & 0xff), value, size, 15);
+}
+
+static const MemoryRegionOps bcm2835_dma0_ops = {
+    .read = bcm2835_dma0_read,
+    .write = bcm2835_dma0_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static const MemoryRegionOps bcm2835_dma15_ops = {
+    .read = bcm2835_dma15_read,
+    .write = bcm2835_dma15_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+};
+
+static const VMStateDescription vmstate_bcm2835_dma_chan = {
+    .name = TYPE_BCM2835_DMA "-chan",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(cs, BCM2835DMAChan),
+        VMSTATE_UINT32(conblk_ad, BCM2835DMAChan),
+        VMSTATE_UINT32(ti, BCM2835DMAChan),
+        VMSTATE_UINT32(source_ad, BCM2835DMAChan),
+        VMSTATE_UINT32(dest_ad, BCM2835DMAChan),
+        VMSTATE_UINT32(txfr_len, BCM2835DMAChan),
+        VMSTATE_UINT32(stride, BCM2835DMAChan),
+        VMSTATE_UINT32(nextconbk, BCM2835DMAChan),
+        VMSTATE_UINT32(debug, BCM2835DMAChan),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_bcm2835_dma = {
+    .name = TYPE_BCM2835_DMA,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(chan, BCM2835DMAState, BCM2835_DMA_NCHANS, 1,
+                             vmstate_bcm2835_dma_chan, BCM2835DMAChan),
+        VMSTATE_UINT32(int_status, BCM2835DMAState),
+        VMSTATE_UINT32(enable, BCM2835DMAState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void bcm2835_dma_init(Object *obj)
+{
+    BCM2835DMAState *s = BCM2835_DMA(obj);
+    int n;
+
+    /* DMA channels 0-14 occupy a contiguous block of IO memory, along
+     * with the global enable and interrupt status bits. Channel 15
+     * has the same register map, but is mapped at a discontiguous
+     * address in a separate IO block.
+     */
+    memory_region_init_io(&s->iomem0, OBJECT(s), &bcm2835_dma0_ops, s,
+                          TYPE_BCM2835_DMA, 0x1000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem0);
+
+    memory_region_init_io(&s->iomem15, OBJECT(s), &bcm2835_dma15_ops, s,
+                          TYPE_BCM2835_DMA "-chan15", 0x100);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem15);
+
+    for (n = 0; n < 16; n++) {
+        sysbus_init_irq(SYS_BUS_DEVICE(s), &s->chan[n].irq);
+    }
+}
+
+static void bcm2835_dma_reset(DeviceState *dev)
+{
+    BCM2835DMAState *s = BCM2835_DMA(dev);
+    int n;
+
+    s->enable = 0xffff;
+    s->int_status = 0;
+    for (n = 0; n < BCM2835_DMA_NCHANS; n++) {
+        bcm2835_dma_chan_reset(&s->chan[n]);
+    }
+}
+
+static void bcm2835_dma_realize(DeviceState *dev, Error **errp)
+{
+    BCM2835DMAState *s = BCM2835_DMA(dev);
+    Error *err = NULL;
+    Object *obj;
+
+    obj = object_property_get_link(OBJECT(dev), "dma-mr", &err);
+    if (obj == NULL) {
+        error_setg(errp, "%s: required dma-mr link not found: %s",
+                   __func__, error_get_pretty(err));
+        return;
+    }
+
+    s->dma_mr = MEMORY_REGION(obj);
+    address_space_init(&s->dma_as, s->dma_mr, NULL);
+
+    bcm2835_dma_reset(dev);
+}
+
+static void bcm2835_dma_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = bcm2835_dma_realize;
+    dc->reset = bcm2835_dma_reset;
+    dc->vmsd = &vmstate_bcm2835_dma;
+}
+
+static TypeInfo bcm2835_dma_info = {
+    .name          = TYPE_BCM2835_DMA,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BCM2835DMAState),
+    .class_init    = bcm2835_dma_class_init,
+    .instance_init = bcm2835_dma_init,
+};
+
+static void bcm2835_dma_register_types(void)
+{
+    type_register_static(&bcm2835_dma_info);
+}
+
+type_init(bcm2835_dma_register_types)
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index e19d360..e12ae37 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -16,6 +16,7 @@
 #include "hw/sysbus.h"
 #include "hw/char/bcm2835_aux.h"
 #include "hw/display/bcm2835_fb.h"
+#include "hw/dma/bcm2835_dma.h"
 #include "hw/intc/bcm2835_ic.h"
 #include "hw/misc/bcm2835_property.h"
 #include "hw/misc/bcm2835_mbox.h"
@@ -37,6 +38,7 @@ typedef struct BCM2835PeripheralState {
     SysBusDevice *uart0;
     BCM2835AuxState aux;
     BCM2835FBState fb;
+    BCM2835DMAState dma;
     BCM2835ICState ic;
     BCM2835PropertyState property;
     BCM2835MboxState mboxes;
diff --git a/include/hw/dma/bcm2835_dma.h b/include/hw/dma/bcm2835_dma.h
new file mode 100644
index 0000000..75312e2
--- /dev/null
+++ b/include/hw/dma/bcm2835_dma.h
@@ -0,0 +1,47 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_DMA_H
+#define BCM2835_DMA_H
+
+#include "qemu-common.h"
+#include "exec/address-spaces.h"
+#include "hw/sysbus.h"
+
+typedef struct {
+    uint32_t cs;
+    uint32_t conblk_ad;
+    uint32_t ti;
+    uint32_t source_ad;
+    uint32_t dest_ad;
+    uint32_t txfr_len;
+    uint32_t stride;
+    uint32_t nextconbk;
+    uint32_t debug;
+
+    qemu_irq irq;
+} BCM2835DMAChan;
+
+#define TYPE_BCM2835_DMA "bcm2835-dma"
+#define BCM2835_DMA(obj) \
+        OBJECT_CHECK(BCM2835DMAState, (obj), TYPE_BCM2835_DMA)
+
+#define BCM2835_DMA_NCHANS 16
+
+typedef struct {
+    /*< private >*/
+    SysBusDevice busdev;
+    /*< public >*/
+
+    MemoryRegion iomem0, iomem15;
+    MemoryRegion *dma_mr;
+    AddressSpace dma_as;
+
+    BCM2835DMAChan chan[BCM2835_DMA_NCHANS];
+    uint32_t int_status;
+    uint32_t enable;
+} BCM2835DMAState;
+
+#endif
-- 
1.9.1

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

* [Qemu-devel] [PULL 21/21] sd: Fix "info qtree" on boards with SD cards
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (19 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 20/21] bcm2835_dma: add emulation of Raspberry Pi DMA controller Peter Maydell
@ 2016-03-16 17:18 ` Peter Maydell
  2016-03-16 17:42 ` [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
  2016-03-16 18:19 ` Peter Maydell
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:18 UTC (permalink / raw)
  To: qemu-devel

The SD card object is not a SysBusDevice, so don't create it with
qdev_create() if we're not assigning it to a specific bus; use
object_new() instead.

This was causing 'info qtree' to segfault on boards with SD cards,
because qdev_create(NULL, TYPE_FOO) puts the created object on the
system bus, and then we may try to run functions like sysbus_dev_print()
on it, which fail when casting the object to SysBusDevice.

(This is the same mistake that we made with the NAND device
and fixed in commit 6749695eaaf346c1.)

Reported-by: xiaoqiang.zhao <zxq_yx_007@163.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: xiaoqiang.zhao <zxq_yx_007@163.com>
Message-id: 1458061009-7733-1-git-send-email-peter.maydell@linaro.org
---
 hw/sd/sd.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 00c320d..1568057 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -563,17 +563,19 @@ static const VMStateDescription sd_vmstate = {
 /* Legacy initialization function for use by non-qdevified callers */
 SDState *sd_init(BlockBackend *blk, bool is_spi)
 {
+    Object *obj;
     DeviceState *dev;
     Error *err = NULL;
 
-    dev = qdev_create(NULL, TYPE_SD_CARD);
+    obj = object_new(TYPE_SD_CARD);
+    dev = DEVICE(obj);
     qdev_prop_set_drive(dev, "drive", blk, &err);
     if (err) {
         error_report("sd_init failed: %s", error_get_pretty(err));
         return NULL;
     }
     qdev_prop_set_bit(dev, "spi", is_spi);
-    object_property_set_bool(OBJECT(dev), true, "realized", &err);
+    object_property_set_bool(obj, true, "realized", &err);
     if (err) {
         error_report("sd_init failed: %s", error_get_pretty(err));
         return NULL;
-- 
1.9.1

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (20 preceding siblings ...)
  2016-03-16 17:18 ` [Qemu-devel] [PULL 21/21] sd: Fix "info qtree" on boards with SD cards Peter Maydell
@ 2016-03-16 17:42 ` Peter Maydell
  2016-03-16 18:19 ` Peter Maydell
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 17:42 UTC (permalink / raw)
  To: QEMU Developers

On 16 March 2016 at 17:18, Peter Maydell <peter.maydell@linaro.org> wrote:
> Here's the target-arm queue; I'm a bit hesitant about the late-landing
> various new board/SoC patches, but they won't affect anybody who isn't
> trying to use those boards, so I think it's OK.
>
> (There are a few other patches on list which I definitely want to
> get in before rc0 but they need a bit more review time I think.)
>
> thanks
> -- PMM
>
>
> The following changes since commit 0ebc03bc065329eaefb6493f5fa7df08df528f2a:
>
>   util/base64.c: Clean includes (2016-03-16 12:48:11 +0000)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20160316
>
> for you to fetch changes up to 10b27d1ab391dbf36f92e1a33179662082401d7a:
>
>   sd: Fix "info qtree" on boards with SD cards (2016-03-16 17:12:46 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * loader: Fix incorrect parameter name in load_image_mr()
>  * Implement MRS (banked) and MSR (banked) instructions
>  * virt: Implement versioning for machine model
>  * i.MX: some initial patches preparing for i.MX6 support
>  * new ASPEED AST2400 SoC and palmetto-bmc machine
>  * bcm2835: add some more raspi2 devices
>  * sd: fix segfault running "info qtree"

Some versions of gcc appear to give false positive 'may be used
uninitialized' warnings about the msr/mrs code:

/home/petmay01/linaro/qemu-for-merges/target-arm/translate.c: In
function ‘gen_msr_banked
.isra.45’:
/home/petmay01/linaro/qemu-for-merges/target-arm/translate.c:4321:17:
error: ‘tgtmode’ ma
y be used uninitialized in this function [-Werror=maybe-uninitialized]
     tcg_tgtmode = tcg_const_i32(tgtmode);
                 ^
/home/petmay01/linaro/qemu-for-merges/target-arm/translate.c:4322:15:
error: ‘regno’ may be used uninitialized in this function
[-Werror=maybe-uninitialized]
     tcg_regno = tcg_const_i32(regno);
               ^
/home/petmay01/linaro/qemu-for-merges/target-arm/translate.c: In
function ‘gen_mrs_banked.isra.48’:
/home/petmay01/linaro/qemu-for-merges/target-arm/translate.c:4343:17:
error: ‘tgtmode’ may be used uninitialized in this function
[-Werror=maybe-uninitialized]
     tcg_tgtmode = tcg_const_i32(tgtmode);
                 ^
/home/petmay01/linaro/qemu-for-merges/target-arm/translate.c:4344:15:
error: ‘regno’ may be used uninitialized in this function
[-Werror=maybe-uninitialized]
     tcg_regno = tcg_const_i32(regno);
               ^

Fixup:
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4308,7 +4308,7 @@ undef:
 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
 {
     TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
-    int tgtmode, regno;
+    int tgtmode = 0, regno = 0;

     if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
         return;
@@ -4330,7 +4330,7 @@ static void gen_msr_banked(DisasContext *s, int
r, int sysm, int rn)
 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
 {
     TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
-    int tgtmode, regno;
+    int tgtmode = 0, regno = 0;

     if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
         return;

which I'll squash into the appropriate patch and respin.

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
                   ` (21 preceding siblings ...)
  2016-03-16 17:42 ` [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
@ 2016-03-16 18:19 ` Peter Maydell
  22 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2016-03-16 18:19 UTC (permalink / raw)
  To: QEMU Developers

On 16 March 2016 at 17:18, Peter Maydell <peter.maydell@linaro.org> wrote:
> Here's the target-arm queue; I'm a bit hesitant about the late-landing
> various new board/SoC patches, but they won't affect anybody who isn't
> trying to use those boards, so I think it's OK.
>
> (There are a few other patches on list which I definitely want to
> get in before rc0 but they need a bit more review time I think.)
>
> thanks
> -- PMM
>
>
> The following changes since commit 0ebc03bc065329eaefb6493f5fa7df08df528f2a:
>
>   util/base64.c: Clean includes (2016-03-16 12:48:11 +0000)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20160316
>
> for you to fetch changes up to 10b27d1ab391dbf36f92e1a33179662082401d7a:
>
>   sd: Fix "info qtree" on boards with SD cards (2016-03-16 17:12:46 +0000)

Respin with fix now applied to master.

-- PMM

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2019-09-03 15:36 Peter Maydell
@ 2019-09-04 13:44 ` Peter Maydell
  0 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2019-09-04 13:44 UTC (permalink / raw)
  To: QEMU Developers

On Tue, 3 Sep 2019 at 16:36, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> target-arm queue: this time around is all small fixes
> and changes.
>
> thanks
> -- PMM
>
> The following changes since commit fec105c2abda8567ec15230429c41429b5ee307c:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/audio-20190828-pull-request' into staging (2019-09-03 14:03:15 +0100)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190903
>
> for you to fetch changes up to 5e5584c89f36b302c666bc6db535fd3f7ff35ad2:
>
>   target/arm: Don't abort on M-profile exception return in linux-user mode (2019-09-03 16:20:35 +0100)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * Revert and correctly fix refactoring of unallocated_encoding()
>  * Take exceptions on ATS instructions when needed
>  * aspeed/timer: Provide back-pressure information for short periods
>  * memory: Remove unused memory_region_iommu_replay_all()
>  * hw/arm/smmuv3: Log a guest error when decoding an invalid STE
>  * hw/arm/smmuv3: Remove spurious error messages on IOVA invalidations
>  * target/arm: Fix SMMLS argument order
>  * hw/arm: Use ARM_CPU_TYPE_NAME() macro when appropriate
>  * hw/arm: Correct reference counting for creation of various objects
>  * includes: remove stale [smp|max]_cpus externs
>  * tcg/README: fix typo
>  * atomic_template: fix indentation in GEN_ATOMIC_HELPER
>  * include/exec/cpu-defs.h: fix typo
>  * target/arm: Free TCG temps in trans_VMOV_64_sp()
>  * target/arm: Don't abort on M-profile exception return in linux-user mode
>
> ----------------------------------------------------------------


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.2
for any user-visible changes.

-- PMM


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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2019-09-03 15:36 Peter Maydell
  2019-09-04 13:44 ` Peter Maydell
  0 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2019-09-03 15:36 UTC (permalink / raw)
  To: qemu-devel

target-arm queue: this time around is all small fixes
and changes.

thanks
-- PMM

The following changes since commit fec105c2abda8567ec15230429c41429b5ee307c:

  Merge remote-tracking branch 'remotes/kraxel/tags/audio-20190828-pull-request' into staging (2019-09-03 14:03:15 +0100)

are available in the Git repository at:

  https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190903

for you to fetch changes up to 5e5584c89f36b302c666bc6db535fd3f7ff35ad2:

  target/arm: Don't abort on M-profile exception return in linux-user mode (2019-09-03 16:20:35 +0100)

----------------------------------------------------------------
target-arm queue:
 * Revert and correctly fix refactoring of unallocated_encoding()
 * Take exceptions on ATS instructions when needed
 * aspeed/timer: Provide back-pressure information for short periods
 * memory: Remove unused memory_region_iommu_replay_all()
 * hw/arm/smmuv3: Log a guest error when decoding an invalid STE
 * hw/arm/smmuv3: Remove spurious error messages on IOVA invalidations
 * target/arm: Fix SMMLS argument order
 * hw/arm: Use ARM_CPU_TYPE_NAME() macro when appropriate
 * hw/arm: Correct reference counting for creation of various objects
 * includes: remove stale [smp|max]_cpus externs
 * tcg/README: fix typo
 * atomic_template: fix indentation in GEN_ATOMIC_HELPER
 * include/exec/cpu-defs.h: fix typo
 * target/arm: Free TCG temps in trans_VMOV_64_sp()
 * target/arm: Don't abort on M-profile exception return in linux-user mode

----------------------------------------------------------------
Alex Bennée (2):
      includes: remove stale [smp|max]_cpus externs
      include/exec/cpu-defs.h: fix typo

Andrew Jeffery (1):
      aspeed/timer: Provide back-pressure information for short periods

Emilio G. Cota (2):
      tcg/README: fix typo s/afterwise/afterwards/
      atomic_template: fix indentation in GEN_ATOMIC_HELPER

Eric Auger (3):
      memory: Remove unused memory_region_iommu_replay_all()
      hw/arm/smmuv3: Log a guest error when decoding an invalid STE
      hw/arm/smmuv3: Remove spurious error messages on IOVA invalidations

Peter Maydell (4):
      target/arm: Allow ARMCPRegInfo read/write functions to throw exceptions
      target/arm: Take exceptions on ATS instructions when needed
      target/arm: Free TCG temps in trans_VMOV_64_sp()
      target/arm: Don't abort on M-profile exception return in linux-user mode

Philippe Mathieu-Daudé (6):
      hw/arm: Use ARM_CPU_TYPE_NAME() macro when appropriate
      hw/arm: Use object_initialize_child for correct reference counting
      hw/arm: Use sysbus_init_child_obj for correct reference counting
      hw/arm/fsl-imx: Add the cpu as child of the SoC object
      hw/dma/xilinx_axi: Use object_initialize_child for correct ref. counting
      hw/net/xilinx_axi: Use object_initialize_child for correct ref. counting

Richard Henderson (3):
      Revert "target/arm: Use unallocated_encoding for aarch32"
      target/arm: Factor out unallocated_encoding for aarch32
      target/arm: Fix SMMLS argument order

 accel/tcg/atomic_template.h    |   2 +-
 hw/arm/smmuv3-internal.h       |   1 +
 include/exec/cpu-defs.h        |   2 +-
 include/exec/memory.h          |  10 ----
 include/sysemu/sysemu.h        |   2 -
 target/arm/cpu.h               |   6 ++-
 target/arm/translate-a64.h     |   2 +
 target/arm/translate.h         |   2 -
 hw/arm/allwinner-a10.c         |   3 +-
 hw/arm/cubieboard.c            |   3 +-
 hw/arm/digic.c                 |   3 +-
 hw/arm/exynos4_boards.c        |   4 +-
 hw/arm/fsl-imx25.c             |   4 +-
 hw/arm/fsl-imx31.c             |   4 +-
 hw/arm/fsl-imx6.c              |   3 +-
 hw/arm/fsl-imx6ul.c            |   2 +-
 hw/arm/mcimx7d-sabre.c         |   9 ++--
 hw/arm/mps2-tz.c               |  15 +++---
 hw/arm/musca.c                 |   9 ++--
 hw/arm/smmuv3.c                |  18 ++++---
 hw/arm/xlnx-zynqmp.c           |   8 +--
 hw/dma/xilinx_axidma.c         |  16 +++---
 hw/net/xilinx_axienet.c        |  17 +++----
 hw/timer/aspeed_timer.c        |  17 ++++++-
 memory.c                       |   9 ----
 target/arm/helper.c            | 107 +++++++++++++++++++++++++++++++++++------
 target/arm/translate-a64.c     |  13 +++++
 target/arm/translate-vfp.inc.c |   2 +
 target/arm/translate.c         |  50 +++++++++++++++++--
 tcg/README                     |   2 +-
 30 files changed, 244 insertions(+), 101 deletions(-)


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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2019-02-21 18:57 Peter Maydell
@ 2019-02-22 11:24 ` Peter Maydell
  0 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2019-02-22 11:24 UTC (permalink / raw)
  To: QEMU Developers

On Thu, 21 Feb 2019 at 18:57, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> Arm queue -- mostly the first slice of my Musca patches.
>
> thanks
> -- PMM
>
> The following changes since commit fc3dbb90f2eb069801bfb4cfe9cbc83cf9c5f4a9:
>
>   Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-02-21 13:09:33 +0000)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190221
>
> for you to fetch changes up to 3733f80308d2a7f23f5e39b039e0547aba6c07f1:
>
>   hw/arm/armsse: Make 0x5... alias region work for per-CPU devices (2019-02-21 18:17:48 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * Model the Arm "Musca" development boards: "musca-a" and "musca-b1"
>  * Implement the ARMv8.3-JSConv extension
>  * v8M MPU should use background region as default, not always
>  * Stop unintentional sign extension in pmu_init
>
> ----------------------------------------------------------------

Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.0
for any user-visible changes.

-- PMM

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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2019-02-21 18:57 Peter Maydell
  2019-02-22 11:24 ` Peter Maydell
  0 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2019-02-21 18:57 UTC (permalink / raw)
  To: qemu-devel

Arm queue -- mostly the first slice of my Musca patches.

thanks
-- PMM

The following changes since commit fc3dbb90f2eb069801bfb4cfe9cbc83cf9c5f4a9:

  Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-02-21 13:09:33 +0000)

are available in the Git repository at:

  https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190221

for you to fetch changes up to 3733f80308d2a7f23f5e39b039e0547aba6c07f1:

  hw/arm/armsse: Make 0x5... alias region work for per-CPU devices (2019-02-21 18:17:48 +0000)

----------------------------------------------------------------
target-arm queue:
 * Model the Arm "Musca" development boards: "musca-a" and "musca-b1"
 * Implement the ARMv8.3-JSConv extension
 * v8M MPU should use background region as default, not always
 * Stop unintentional sign extension in pmu_init

----------------------------------------------------------------
Aaron Lindsay OS (1):
      target/arm: Stop unintentional sign extension in pmu_init

Peter Maydell (16):
      hw/arm/armsse: Fix memory leak in error-exit path
      target/arm: v8M MPU should use background region as default, not always
      hw/misc/tz-ppc: Support having unused ports in the middle of the range
      hw/timer/pl031: Allow use as an embedded-struct device
      hw/timer/pl031: Convert to using trace events
      hw/char/pl011: Allow use as an embedded-struct device
      hw/char/pl011: Support all interrupt lines
      hw/char/pl011: Use '0x' prefix when logging hex numbers
      hw/arm/armsse: Document SRAM_ADDR_WIDTH property in header comment
      hw/arm/armsse: Allow boards to specify init-svtor
      hw/arm/musca.c: Implement models of the Musca-A and -B1 boards
      hw/arm/musca: Add PPCs
      hw/arm/musca: Add MPCs
      hw/arm/musca: Wire up PL031 RTC
      hw/arm/musca: Wire up PL011 UARTs
      hw/arm/armsse: Make 0x5... alias region work for per-CPU devices

Richard Henderson (4):
      target/arm: Restructure disas_fp_int_conv
      target/arm: Split out vfp_helper.c
      target/arm: Rearrange Floating-point data-processing (2 regs)
      target/arm: Implement ARMv8.3-JSConv

 hw/arm/Makefile.objs            |    1 +
 target/arm/Makefile.objs        |    2 +-
 include/hw/arm/armsse.h         |    7 +-
 include/hw/char/pl011.h         |   34 ++
 include/hw/misc/tz-ppc.h        |    8 +-
 include/hw/timer/pl031.h        |   44 ++
 target/arm/cpu.h                |   10 +
 target/arm/helper.h             |    3 +
 hw/arm/armsse.c                 |   44 +-
 hw/arm/musca.c                  |  669 ++++++++++++++++++++++
 hw/char/pl011.c                 |   81 +--
 hw/misc/tz-ppc.c                |   32 ++
 hw/timer/pl031.c                |   80 ++-
 target/arm/cpu.c                |    1 +
 target/arm/cpu64.c              |    2 +
 target/arm/helper.c             | 1072 +----------------------------------
 target/arm/translate-a64.c      |  120 ++--
 target/arm/translate.c          |  237 ++++----
 target/arm/vfp_helper.c         | 1176 +++++++++++++++++++++++++++++++++++++++
 MAINTAINERS                     |    7 +
 default-configs/arm-softmmu.mak |    1 +
 hw/timer/trace-events           |    6 +
 22 files changed, 2307 insertions(+), 1330 deletions(-)
 create mode 100644 include/hw/timer/pl031.h
 create mode 100644 hw/arm/musca.c
 create mode 100644 target/arm/vfp_helper.c

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2018-05-10 17:44 Peter Maydell
  2018-05-10 18:06 ` no-reply
@ 2018-05-14  8:46 ` Peter Maydell
  1 sibling, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2018-05-14  8:46 UTC (permalink / raw)
  To: QEMU Developers

On 10 May 2018 at 18:44, Peter Maydell <peter.maydell@linaro.org> wrote:
> The following changes since commit e5cd695266c5709308aa95b1baae499e4b5d4544:
>
>   Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging (2018-05-08 17:05:58 +0100)
>
> are available in the Git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180510
>
> for you to fetch changes up to 9a9f1f59521f46e8ff4527d9a2b52f83577e2aa3:
>
>   target/arm: Clear SVE high bits for FMOV (2018-05-10 18:10:58 +0100)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * hw/arm/iotkit.c: fix minor memory leak
>  * softfloat: fix wrong-exception-flags bug for multiply-add corner case
>  * arm: isolate and clean up DTB generation
>  * implement Arm v8.1-Atomics extension
>  * Fix some bugs and missing instructions in the v8.2-FP16 extension
>

Applied, thanks.

-- PMM

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2018-05-10 17:44 Peter Maydell
@ 2018-05-10 18:06 ` no-reply
  2018-05-14  8:46 ` Peter Maydell
  1 sibling, 0 replies; 42+ messages in thread
From: no-reply @ 2018-05-10 18:06 UTC (permalink / raw)
  To: peter.maydell; +Cc: famz, qemu-devel

Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20180510174519.11264-1-peter.maydell@linaro.org
Subject: [Qemu-devel] [PULL 00/21] target-arm queue

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 t [tag update]            patchew/20180502221552.3873-1-richard.henderson@linaro.org -> patchew/20180502221552.3873-1-richard.henderson@linaro.org
 t [tag update]            patchew/20180503115620.10596-1-edgar.iglesias@gmail.com -> patchew/20180503115620.10596-1-edgar.iglesias@gmail.com
 t [tag update]            patchew/20180509165530.29561-1-mreitz@redhat.com -> patchew/20180509165530.29561-1-mreitz@redhat.com
 t [tag update]            patchew/20180510094206.15354-1-alex.bennee@linaro.org -> patchew/20180510094206.15354-1-alex.bennee@linaro.org
 t [tag update]            patchew/20180510140141.12120-1-peter.maydell@linaro.org -> patchew/20180510140141.12120-1-peter.maydell@linaro.org
 t [tag update]            patchew/20180510140934.22855-1-peter.maydell@linaro.org -> patchew/20180510140934.22855-1-peter.maydell@linaro.org
 t [tag update]            patchew/20180510143618.23673-1-peter.maydell@linaro.org -> patchew/20180510143618.23673-1-peter.maydell@linaro.org
 * [new tag]               patchew/20180510174519.11264-1-peter.maydell@linaro.org -> patchew/20180510174519.11264-1-peter.maydell@linaro.org
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
Switched to a new branch 'test'
ccdba81c4b target/arm: Clear SVE high bits for FMOV
64003f64f0 target/arm: Fix float16 to/from int16
600be1201a target/arm: Implement vector shifted FCVT for fp16
0f941356c9 target/arm: Implement vector shifted SCVF/UCVF for fp16
3ded533d22 target/arm: Enable ARM_FEATURE_V8_ATOMICS for user-only
9d58b9b45c target/arm: Implement CAS and CASP
51a26a9014 target/arm: Fill in disas_ldst_atomic
de4ccb142c target/arm: Introduce ARM_FEATURE_V8_ATOMICS and initial decode
3b7e02239c target/riscv: Use new atomic min/max expanders
d8820204cf tcg: Use GEN_ATOMIC_HELPER_FN for opposite endian atomic add
587522510f tcg: Introduce atomic helpers for integer min/max
adbe86c2cb target/xtensa: Use new min/max expanders
9f9ed0f8b4 target/arm: Use new min/max expanders
0386c2a4f5 tcg: Introduce helpers for integer min/max
7a13cbc1df atomic.h: Work around gcc spurious "unused value" warning
704fd2643a make sure that we aren't overwriting mc->get_hotplug_handler by accident
e35977cfc3 arm/boot: split load_dtb() from arm_load_kernel()
b46a5f4740 platform-bus-device: use device plug callback instead of machine_done notifier
318eae8151 pc: simplify MachineClass::get_hotplug_handler handling
d99828cef6 softfloat: Handle default NaN mode after pickNaNMulAdd, not before
058260b178 hw/arm/iotkit.c: fix minor memory leak

=== OUTPUT BEGIN ===
Checking PATCH 1/21: hw/arm/iotkit.c: fix minor memory leak...
Checking PATCH 2/21: softfloat: Handle default NaN mode after pickNaNMulAdd, not before...
Checking PATCH 3/21: pc: simplify MachineClass::get_hotplug_handler handling...
Checking PATCH 4/21: platform-bus-device: use device plug callback instead of machine_done notifier...
Checking PATCH 5/21: arm/boot: split load_dtb() from arm_load_kernel()...
Checking PATCH 6/21: make sure that we aren't overwriting mc->get_hotplug_handler by accident...
Checking PATCH 7/21: atomic.h: Work around gcc spurious "unused value" warning...
Checking PATCH 8/21: tcg: Introduce helpers for integer min/max...
Checking PATCH 9/21: target/arm: Use new min/max expanders...
Checking PATCH 10/21: target/xtensa: Use new min/max expanders...
Checking PATCH 11/21: tcg: Introduce atomic helpers for integer min/max...
ERROR: memory barrier without comment
#58: FILE: accel/tcg/atomic_template.h:137:
+    smp_mb();                                                       \

ERROR: memory barrier without comment
#98: FILE: accel/tcg/atomic_template.h:285:
+    smp_mb();                                                       \

total: 2 errors, 0 warnings, 236 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 12/21: tcg: Use GEN_ATOMIC_HELPER_FN for opposite endian atomic add...
Checking PATCH 13/21: target/riscv: Use new atomic min/max expanders...
Checking PATCH 14/21: target/arm: Introduce ARM_FEATURE_V8_ATOMICS and initial decode...
Checking PATCH 15/21: target/arm: Fill in disas_ldst_atomic...
Checking PATCH 16/21: target/arm: Implement CAS and CASP...
Checking PATCH 17/21: target/arm: Enable ARM_FEATURE_V8_ATOMICS for user-only...
Checking PATCH 18/21: target/arm: Implement vector shifted SCVF/UCVF for fp16...
Checking PATCH 19/21: target/arm: Implement vector shifted FCVT for fp16...
Checking PATCH 20/21: target/arm: Fix float16 to/from int16...
ERROR: spaces required around that '*' (ctx:WxV)
#47: FILE: target/arm/helper.c:11434:
+static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
                                                                     ^

total: 1 errors, 0 warnings, 83 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 21/21: target/arm: Clear SVE high bits for FMOV...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2018-05-10 17:44 Peter Maydell
  2018-05-10 18:06 ` no-reply
  2018-05-14  8:46 ` Peter Maydell
  0 siblings, 2 replies; 42+ messages in thread
From: Peter Maydell @ 2018-05-10 17:44 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit e5cd695266c5709308aa95b1baae499e4b5d4544:

  Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging (2018-05-08 17:05:58 +0100)

are available in the Git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180510

for you to fetch changes up to 9a9f1f59521f46e8ff4527d9a2b52f83577e2aa3:

  target/arm: Clear SVE high bits for FMOV (2018-05-10 18:10:58 +0100)

----------------------------------------------------------------
target-arm queue:
 * hw/arm/iotkit.c: fix minor memory leak
 * softfloat: fix wrong-exception-flags bug for multiply-add corner case
 * arm: isolate and clean up DTB generation
 * implement Arm v8.1-Atomics extension
 * Fix some bugs and missing instructions in the v8.2-FP16 extension

----------------------------------------------------------------
Igor Mammedov (4):
      pc: simplify MachineClass::get_hotplug_handler handling
      platform-bus-device: use device plug callback instead of machine_done notifier
      arm/boot: split load_dtb() from arm_load_kernel()
      make sure that we aren't overwriting mc->get_hotplug_handler by accident

Peter Maydell (3):
      hw/arm/iotkit.c: fix minor memory leak
      softfloat: Handle default NaN mode after pickNaNMulAdd, not before
      atomic.h: Work around gcc spurious "unused value" warning

Richard Henderson (14):
      tcg: Introduce helpers for integer min/max
      target/arm: Use new min/max expanders
      target/xtensa: Use new min/max expanders
      tcg: Introduce atomic helpers for integer min/max
      tcg: Use GEN_ATOMIC_HELPER_FN for opposite endian atomic add
      target/riscv: Use new atomic min/max expanders
      target/arm: Introduce ARM_FEATURE_V8_ATOMICS and initial decode
      target/arm: Fill in disas_ldst_atomic
      target/arm: Implement CAS and CASP
      target/arm: Enable ARM_FEATURE_V8_ATOMICS for user-only
      target/arm: Implement vector shifted SCVF/UCVF for fp16
      target/arm: Implement vector shifted FCVT for fp16
      target/arm: Fix float16 to/from int16
      target/arm: Clear SVE high bits for FMOV

 accel/tcg/atomic_template.h | 112 ++++++----
 accel/tcg/tcg-runtime.h     |   8 +
 hw/ppc/e500.h               |   5 +
 include/hw/arm/arm.h        |  45 +++-
 include/hw/arm/sysbus-fdt.h |  37 +---
 include/hw/arm/virt.h       |   1 +
 include/hw/i386/pc.h        |   8 -
 include/hw/platform-bus.h   |   4 +-
 include/qemu/atomic.h       |   2 +-
 target/arm/cpu.h            |   1 +
 target/arm/helper-a64.h     |   2 +
 target/arm/helper.h         |   4 +-
 tcg/tcg-op.h                |  50 +++++
 tcg/tcg.h                   |   8 +
 fpu/softfloat.c             |  52 +++--
 hw/arm/boot.c               |  72 ++-----
 hw/arm/iotkit.c             |   1 +
 hw/arm/sysbus-fdt.c         |  64 +-----
 hw/arm/virt.c               |  96 ++++++---
 hw/core/platform-bus.c      |  29 +--
 hw/i386/pc.c                |   7 +-
 hw/ppc/e500.c               |  38 ++--
 hw/ppc/e500plat.c           |  32 +++
 hw/ppc/spapr.c              |   1 +
 hw/s390x/s390-virtio-ccw.c  |   1 +
 linux-user/elfload.c        |   1 +
 target/arm/cpu64.c          |   1 +
 target/arm/helper-a64.c     |  43 ++++
 target/arm/helper.c         |  53 ++++-
 target/arm/translate-a64.c  | 490 +++++++++++++++++++++++++++++++++-----------
 target/riscv/translate.c    |  72 ++-----
 target/xtensa/translate.c   |  50 +++--
 tcg/tcg-op.c                |  48 +++++
 33 files changed, 934 insertions(+), 504 deletions(-)

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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2018-02-15 13:56 Peter Maydell
  0 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2018-02-15 13:56 UTC (permalink / raw)
  To: qemu-devel

target-arm queue: mostly just cleanup/minor stuff, but this does
include the raspi3 board model.

-- PMM

The following changes since commit 9f9c53368b219a9115eddb39f0ff5ad19c977134:

  Merge remote-tracking branch 'remotes/vivier/tags/m68k-for-2.12-pull-request' into staging (2018-02-15 10:14:11 +0000)

are available in the Git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180215

for you to fetch changes up to e545f0f9be1f9e60951017c1e6558216732cc14e:

  target/arm: Implement v8M MSPLIM and PSPLIM registers (2018-02-15 13:48:11 +0000)

----------------------------------------------------------------
target-arm queue:
 * aspeed: code cleanup to use unimplemented_device
 * add 'raspi3' RaspberryPi 3 machine model
 * more SVE prep work
 * v8M: add minor missing registers
 * v7M: fix bug where we weren't migrating v7m.other_sp
 * v7M: fix bugs in handling of interrupt registers for
   external interrupts beyond 32

----------------------------------------------------------------
Pekka Enberg (3):
      bcm2836: Make CPU type configurable
      raspi: Raspberry Pi 3 support
      raspi: Add "raspi3" machine type

Peter Maydell (11):
      hw/intc/armv7m_nvic: Don't hardcode M profile ID registers in NVIC
      hw/intc/armv7m_nvic: Fix ICSR PENDNMISET/CLR handling
      hw/intc/armv7m_nvic: Implement M profile cache maintenance ops
      hw/intc/armv7m_nvic: Implement v8M CPPWR register
      hw/intc/armv7m_nvic: Implement cache ID registers
      hw/intc/armv7m_nvic: Implement SCR
      target/arm: Implement writing to CONTROL_NS for v8M
      hw/intc/armv7m_nvic: Fix byte-to-interrupt number conversions
      target/arm: Add AIRCR to vmstate struct
      target/arm: Migrate v7m.other_sp
      target/arm: Implement v8M MSPLIM and PSPLIM registers

Philippe Mathieu-Daudé (2):
      hw/arm/aspeed: directly map the serial device to the system address space
      hw/arm/aspeed: simplify using the 'unimplemented device' for aspeed_soc.io

Richard Henderson (5):
      target/arm: Remove ARM_CP_64BIT from ZCR_EL registers
      target/arm: Enforce FP access to FPCR/FPSR
      target/arm: Suppress TB end for FPCR/FPSR
      target/arm: Enforce access to ZCR_EL at translation
      target/arm: Handle SVE registers when using clear_vec_high

 include/hw/arm/aspeed_soc.h |   1 -
 include/hw/arm/bcm2836.h    |   1 +
 target/arm/cpu.h            |  71 ++++++++++++-----
 target/arm/internals.h      |   6 ++
 hw/arm/aspeed_soc.c         |  35 ++-------
 hw/arm/bcm2836.c            |  17 +++--
 hw/arm/raspi.c              |  57 +++++++++++---
 hw/intc/armv7m_nvic.c       |  98 ++++++++++++++++++------
 target/arm/cpu.c            |  28 +++++++
 target/arm/helper.c         |  84 +++++++++++++++-----
 target/arm/machine.c        |  84 ++++++++++++++++++++
 target/arm/translate-a64.c  | 181 ++++++++++++++++++++------------------------
 12 files changed, 452 insertions(+), 211 deletions(-)

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2018-01-25 13:43 Peter Maydell
  2018-01-25 14:18 ` no-reply
@ 2018-01-25 18:06 ` Peter Maydell
  1 sibling, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2018-01-25 18:06 UTC (permalink / raw)
  To: QEMU Developers

On 25 January 2018 at 13:43, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> Arm queue built up to a point where it seems worth sending:
> various bug fixes, plus RTH's refactoring in preparation for SVE.
>
> thanks
> -- PMM
>
>
> The following changes since commit 0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d:
>
>   Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-2.12-pull-request' into staging (2018-01-25 09:53:53 +0000)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180125
>
> for you to fetch changes up to 24da047af0e99a83fcc0d50b86c0f2627f7418b3:
>
>   pl110: Implement vertical compare/next base interrupts (2018-01-25 11:45:30 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * target/arm: Fix address truncation in 64-bit pagetable walks
>  * i.MX: Fix FEC/ENET receive functions
>  * target/arm: preparatory refactoring for SVE emulation
>  * hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
>  * hw/intc/arm_gic: Fix C_RPR value on idle priority
>  * hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
>  * hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
>  * hw/arm/virt: Check that the CPU realize method succeeded
>  * sdhci: fix a NULL pointer dereference due to uninitialized AddressSpace object
>  * xilinx_spips: Correct usage of an uninitialized local variable
>  * pl110: Implement vertical compare/next base interrupts
>

Applied, thanks.

-- PMM

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2018-01-25 13:43 Peter Maydell
@ 2018-01-25 14:18 ` no-reply
  2018-01-25 18:06 ` Peter Maydell
  1 sibling, 0 replies; 42+ messages in thread
From: no-reply @ 2018-01-25 14:18 UTC (permalink / raw)
  To: peter.maydell; +Cc: famz, qemu-devel

Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1516887809-6265-1-git-send-email-peter.maydell@linaro.org
Subject: [Qemu-devel] [PULL 00/21] target-arm queue

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]               patchew/1516887809-6265-1-git-send-email-peter.maydell@linaro.org -> patchew/1516887809-6265-1-git-send-email-peter.maydell@linaro.org
Switched to a new branch 'test'
a7ead1ca00 pl110: Implement vertical compare/next base interrupts
f66ce5c2c3 xilinx_spips: Correct usage of an uninitialized local variable
d88421481d sdhci: fix a NULL pointer dereference due to uninitialized AddresSpace object
7564bd6dfb hw/arm/virt: Check that the CPU realize method succeeded
18db7a35b4 hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
157a918a47 hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
a896e5197e hw/intc/arm_gic: Fix C_RPR value on idle priority
ed702de6c2 hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
0c5df69251 target/arm: Simplify fp_exception_el for user-only
0901e742d2 target/arm: Hoist store to flags output in cpu_get_tb_cpu_state
30d076c766 target/arm: Move cpu_get_tb_cpu_state out of line
9bc4918ade target/arm: Add ARM_FEATURE_SVE
9afce6e002 vmstate: Add VMSTATE_UINT64_SUB_ARRAY
911f6046fd target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers
768420eeb2 target/arm: Change the type of vfp.regs
d2beafabf0 target/arm: Use pointers in neon tbl helper
e00821354c target/arm: Use pointers in neon zip/uzp helpers
ac24cb1f18 target/arm: Use pointers in crypto helpers
df207ebf53 target/arm: Mark disas_set_insn_syndrome inline
a13bffeacc i.MX: Fix FEC/ENET receive funtions
cc82dfe8c8 target/arm: Fix 32-bit address truncation

=== OUTPUT BEGIN ===
Checking PATCH 1/21: target/arm: Fix 32-bit address truncation...
Checking PATCH 2/21: i.MX: Fix FEC/ENET receive funtions...
Checking PATCH 3/21: target/arm: Mark disas_set_insn_syndrome inline...
Checking PATCH 4/21: target/arm: Use pointers in crypto helpers...
Checking PATCH 5/21: target/arm: Use pointers in neon zip/uzp helpers...
ERROR: trailing whitespace
#321: FILE: target/arm/translate.c:4691:
+    $

total: 1 errors, 0 warnings, 373 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 6/21: target/arm: Use pointers in neon tbl helper...
Checking PATCH 7/21: target/arm: Change the type of vfp.regs...
Checking PATCH 8/21: target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers...
ERROR: spaces required around that '*' (ctx:VxV)
#88: FILE: target/arm/arch_dump.c:104:
+        note.vfp.vregs[2*i + 0] = cpu_to_dump64(s, q[0]);
                         ^

ERROR: spaces required around that '*' (ctx:VxV)
#89: FILE: target/arm/arch_dump.c:105:
+        note.vfp.vregs[2*i + 1] = cpu_to_dump64(s, q[1]);
                         ^

total: 2 errors, 0 warnings, 327 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 9/21: vmstate: Add VMSTATE_UINT64_SUB_ARRAY...
Checking PATCH 10/21: target/arm: Add ARM_FEATURE_SVE...
Checking PATCH 11/21: target/arm: Move cpu_get_tb_cpu_state out of line...
Checking PATCH 12/21: target/arm: Hoist store to flags output in cpu_get_tb_cpu_state...
Checking PATCH 13/21: target/arm: Simplify fp_exception_el for user-only...
Checking PATCH 14/21: hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"...
Checking PATCH 15/21: hw/intc/arm_gic: Fix C_RPR value on idle priority...
Checking PATCH 16/21: hw/intc/arm_gic: Fix group priority computation for group 1 IRQs...
Checking PATCH 17/21: hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1...
Checking PATCH 18/21: hw/arm/virt: Check that the CPU realize method succeeded...
Checking PATCH 19/21: sdhci: fix a NULL pointer dereference due to uninitialized AddresSpace object...
Checking PATCH 20/21: xilinx_spips: Correct usage of an uninitialized local variable...
Checking PATCH 21/21: pl110: Implement vertical compare/next base interrupts...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2018-01-25 13:43 Peter Maydell
  2018-01-25 14:18 ` no-reply
  2018-01-25 18:06 ` Peter Maydell
  0 siblings, 2 replies; 42+ messages in thread
From: Peter Maydell @ 2018-01-25 13:43 UTC (permalink / raw)
  To: qemu-devel


Arm queue built up to a point where it seems worth sending:
various bug fixes, plus RTH's refactoring in preparation for SVE.

thanks
-- PMM
 
 
The following changes since commit 0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d:

  Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-2.12-pull-request' into staging (2018-01-25 09:53:53 +0000)

are available in the git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180125

for you to fetch changes up to 24da047af0e99a83fcc0d50b86c0f2627f7418b3:

  pl110: Implement vertical compare/next base interrupts (2018-01-25 11:45:30 +0000)

----------------------------------------------------------------
target-arm queue:
 * target/arm: Fix address truncation in 64-bit pagetable walks
 * i.MX: Fix FEC/ENET receive functions
 * target/arm: preparatory refactoring for SVE emulation
 * hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
 * hw/intc/arm_gic: Fix C_RPR value on idle priority
 * hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
 * hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
 * hw/arm/virt: Check that the CPU realize method succeeded
 * sdhci: fix a NULL pointer dereference due to uninitialized AddressSpace object
 * xilinx_spips: Correct usage of an uninitialized local variable
 * pl110: Implement vertical compare/next base interrupts

----------------------------------------------------------------
Ard Biesheuvel (1):
      target/arm: Fix 32-bit address truncation

Francisco Iglesias (1):
      xilinx_spips: Correct usage of an uninitialized local variable

Jean-Christophe Dubois (1):
      i.MX: Fix FEC/ENET receive funtions

Linus Walleij (1):
      pl110: Implement vertical compare/next base interrupts

Luc MICHEL (4):
      hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
      hw/intc/arm_gic: Fix C_RPR value on idle priority
      hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
      hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1

Peter Maydell (1):
      hw/arm/virt: Check that the CPU realize method succeeded

Philippe Mathieu-Daudé (1):
      sdhci: fix a NULL pointer dereference due to uninitialized AddresSpace object

Richard Henderson (11):
      target/arm: Mark disas_set_insn_syndrome inline
      target/arm: Use pointers in crypto helpers
      target/arm: Use pointers in neon zip/uzp helpers
      target/arm: Use pointers in neon tbl helper
      target/arm: Change the type of vfp.regs
      target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers
      vmstate: Add VMSTATE_UINT64_SUB_ARRAY
      target/arm: Add ARM_FEATURE_SVE
      target/arm: Move cpu_get_tb_cpu_state out of line
      target/arm: Hoist store to flags output in cpu_get_tb_cpu_state
      target/arm: Simplify fp_exception_el for user-only

 include/hw/sd/sdhci.h       |   1 +
 include/migration/vmstate.h |   9 ++-
 target/arm/cpu.h            | 157 ++++++++-----------------------------
 target/arm/helper.h         |  46 +++++------
 target/arm/translate.h      |   2 +-
 hw/arm/virt.c               |   2 +-
 hw/display/pl110.c          |  30 +++++++-
 hw/intc/arm_gic.c           |  25 +++++-
 hw/net/imx_fec.c            |   8 +-
 hw/sd/sdhci.c               |   1 +
 hw/ssi/xilinx_spips.c       |  18 ++++-
 linux-user/signal.c         |  22 +++---
 target/arm/arch_dump.c      |   8 +-
 target/arm/crypto_helper.c  | 184 +++++++++++++++++---------------------------
 target/arm/helper-a64.c     |   5 +-
 target/arm/helper.c         | 164 +++++++++++++++++++++++++++++++++++----
 target/arm/kvm32.c          |   4 +-
 target/arm/kvm64.c          |  31 +++-----
 target/arm/machine.c        |   2 +-
 target/arm/neon_helper.c    | 162 ++++++++++++++++++++------------------
 target/arm/op_helper.c      |  17 ++--
 target/arm/translate-a64.c  | 100 ++++++++++++------------
 target/arm/translate.c      | 134 +++++++++++++++++---------------
 23 files changed, 607 insertions(+), 525 deletions(-)

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2017-02-28 17:15 Peter Maydell
@ 2017-03-01 19:28 ` Peter Maydell
  0 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2017-03-01 19:28 UTC (permalink / raw)
  To: QEMU Developers

On 28 February 2017 at 17:15, Peter Maydell <peter.maydell@linaro.org> wrote:
> Second lot of ARM changes to sneak in before freeze:
>  * fixed version of the raspi2 sd controller patches
>  * GICv3 save/restore
>  * v7M QOMify
>
> I've also included the Linux header update patches stolen
> from Paolo's pullreq since it hasn't quite hit master yet.
>
> thanks
> -- PMM
>
> The following changes since commit 1bbe5dc66b770d7bedd1d51d7935da948a510dd6:
>
>   Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170228' into staging (2017-02-28 14:50:17 +0000)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170228-1
>
> for you to fetch changes up to 1eeb5c7deacbfb4d4cad17590a16a99f3d85eabb:
>
>   bcm2835: add sdhost and gpio controllers (2017-02-28 17:10:00 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * raspi2: add gpio controller and sdhost controller, with
>    the wiring so the guest can switch which controller the
>    SD card is attached to
>    (this is sufficient to get raspbian kernels to boot)
>  * GICv3: support state save/restore from KVM
>  * update Linux headers to 4.11
>  * refactor and QOMify the ARMv7M container object

Applied, thanks.

-- PMM

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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2017-02-28 17:15 Peter Maydell
  2017-03-01 19:28 ` Peter Maydell
  0 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2017-02-28 17:15 UTC (permalink / raw)
  To: qemu-devel

Second lot of ARM changes to sneak in before freeze:
 * fixed version of the raspi2 sd controller patches
 * GICv3 save/restore
 * v7M QOMify

I've also included the Linux header update patches stolen
from Paolo's pullreq since it hasn't quite hit master yet.

thanks
-- PMM

The following changes since commit 1bbe5dc66b770d7bedd1d51d7935da948a510dd6:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170228' into staging (2017-02-28 14:50:17 +0000)

are available in the git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170228-1

for you to fetch changes up to 1eeb5c7deacbfb4d4cad17590a16a99f3d85eabb:

  bcm2835: add sdhost and gpio controllers (2017-02-28 17:10:00 +0000)

----------------------------------------------------------------
target-arm queue:
 * raspi2: add gpio controller and sdhost controller, with
   the wiring so the guest can switch which controller the
   SD card is attached to
   (this is sufficient to get raspbian kernels to boot)
 * GICv3: support state save/restore from KVM
 * update Linux headers to 4.11
 * refactor and QOMify the ARMv7M container object

----------------------------------------------------------------
Clement Deschamps (3):
      hw/sd: add card-reparenting function
      bcm2835_gpio: add bcm2835 gpio controller
      bcm2835: add sdhost and gpio controllers

Paolo Bonzini (2):
      update-linux-headers: update for 4.11
      update Linux headers to 4.11

Peter Maydell (12):
      armv7m: Abstract out the "load kernel" code
      armv7m: Move NVICState struct definition into header
      armv7m: QOMify the armv7m container
      armv7m: Use QOMified armv7m object in armv7m_init()
      armv7m: Make ARMv7M object take memory region link
      armv7m: Make NVIC expose a memory region rather than mapping itself
      armv7m: Make bitband device take the address space to access
      armv7m: Don't put core v7M devices under CONFIG_STELLARIS
      armv7m: Split systick out from NVIC
      stm32f205: Create armv7m object without using armv7m_init()
      stm32f205: Rename 'nvic' local to 'armv7m'
      qdev: Have qdev_set_parent_bus() handle devices already on a bus

Vijaya Kumar K (4):
      hw/intc/arm_gicv3_kvm: Add ICC_SRE_EL1 register to vmstate
      hw/intc/arm_gicv3_kvm: Implement get/put functions
      target-arm: Add GICv3CPUState in CPUARMState struct
      hw/intc/arm_gicv3_kvm: Reset GICv3 cpu interface registers

 hw/gpio/Makefile.objs                              |   1 +
 hw/intc/Makefile.objs                              |   2 +-
 hw/timer/Makefile.objs                             |   1 +
 hw/intc/gicv3_internal.h                           |   3 +
 include/hw/arm/arm.h                               |  12 +
 include/hw/arm/armv7m.h                            |  63 +++
 include/hw/arm/armv7m_nvic.h                       |  62 ++
 include/hw/arm/bcm2835_peripherals.h               |   4 +
 include/hw/arm/stm32f205_soc.h                     |   4 +-
 include/hw/gpio/bcm2835_gpio.h                     |  39 ++
 include/hw/intc/arm_gicv3_common.h                 |   1 +
 include/hw/sd/sd.h                                 |  11 +
 include/hw/timer/armv7m_systick.h                  |  34 ++
 include/standard-headers/asm-x86/hyperv.h          |   8 +
 include/standard-headers/linux/input-event-codes.h |   2 +-
 include/standard-headers/linux/pci_regs.h          |  25 +
 include/standard-headers/linux/virtio_ids.h        |   1 +
 linux-headers/asm-arm/kvm.h                        |  15 +
 linux-headers/asm-arm/unistd-common.h              | 357 ++++++++++++
 linux-headers/asm-arm/unistd-eabi.h                |   5 +
 linux-headers/asm-arm/unistd-oabi.h                |  17 +
 linux-headers/asm-arm/unistd.h                     | 419 +-------------
 linux-headers/asm-arm64/kvm.h                      |  13 +
 linux-headers/asm-powerpc/kvm.h                    |  27 +
 linux-headers/asm-powerpc/unistd.h                 |   1 +
 linux-headers/asm-x86/kvm_para.h                   |  13 +-
 linux-headers/linux/kvm.h                          |  24 +-
 linux-headers/linux/kvm_para.h                     |   2 +
 linux-headers/linux/userfaultfd.h                  |  67 ++-
 linux-headers/linux/vfio.h                         |  10 +
 target/arm/cpu.h                                   |   2 +
 hw/arm/armv7m.c                                    | 379 ++++++++-----
 hw/arm/bcm2835_peripherals.c                       |  43 +-
 hw/arm/netduino2.c                                 |   7 +-
 hw/arm/stm32f205_soc.c                             |  28 +-
 hw/core/qdev.c                                     |  14 +
 hw/gpio/bcm2835_gpio.c                             | 353 ++++++++++++
 hw/intc/arm_gicv3_common.c                         |  38 ++
 hw/intc/arm_gicv3_cpuif.c                          |   8 +
 hw/intc/arm_gicv3_kvm.c                            | 629 ++++++++++++++++++++-
 hw/intc/armv7m_nvic.c                              | 214 ++-----
 hw/sd/core.c                                       |  27 +
 hw/timer/armv7m_systick.c                          | 240 ++++++++
 default-configs/arm-softmmu.mak                    |   2 +
 hw/timer/trace-events                              |   6 +
 scripts/update-linux-headers.sh                    |  13 +-
 46 files changed, 2479 insertions(+), 767 deletions(-)
 create mode 100644 include/hw/arm/armv7m.h
 create mode 100644 include/hw/arm/armv7m_nvic.h
 create mode 100644 include/hw/gpio/bcm2835_gpio.h
 create mode 100644 include/hw/timer/armv7m_systick.h
 create mode 100644 linux-headers/asm-arm/unistd-common.h
 create mode 100644 linux-headers/asm-arm/unistd-eabi.h
 create mode 100644 linux-headers/asm-arm/unistd-oabi.h
 create mode 100644 hw/gpio/bcm2835_gpio.c
 create mode 100644 hw/timer/armv7m_systick.c

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2017-01-09 11:53 Peter Maydell
@ 2017-01-09 13:44 ` Peter Maydell
  0 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2017-01-09 13:44 UTC (permalink / raw)
  To: QEMU Developers

On 9 January 2017 at 11:53, Peter Maydell <peter.maydell@linaro.org> wrote:
> target-arm queue: nothing hugely exciting here, the
> bulk is Andrew's virt-acpi-build refactorings.
>
> thanks
> -- PMM
>
> The following changes since commit ffe22bf51065dd33022cf91f77a821d1f11c250d:
>
>   Merge remote-tracking branch 'remotes/gonglei/tags/cryptodev-next-20161224' into staging (2017-01-06 15:18:09 +0000)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170109
>
> for you to fetch changes up to 556899fc1965d82f5c4a3ba6a0be3b1193e2c4b2:
>
>   hw/ssi/imx_spi.c: Remove MSGDATA register support (2017-01-09 11:50:23 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * i2c: Allow I2C devices to NAK start events
>  * hw/char: QOM'ify exynos4210_uart.c
>  * clean up and refactor virt-acpi-build.c
>  * virt-acpi-build: Don't incorrectly claim architectural timer
>    to be edge-triggered
>  * m25p80: Don't let rogue SPI controllers cause buffer overruns
>  * imx_spi: Remove broken MSGDATA register support
>
> ----------------------------------------------------------------

Applied, thanks.

-- PMM

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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2017-01-09 11:53 Peter Maydell
  2017-01-09 13:44 ` Peter Maydell
  0 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2017-01-09 11:53 UTC (permalink / raw)
  To: qemu-devel

target-arm queue: nothing hugely exciting here, the
bulk is Andrew's virt-acpi-build refactorings.

thanks
-- PMM

The following changes since commit ffe22bf51065dd33022cf91f77a821d1f11c250d:

  Merge remote-tracking branch 'remotes/gonglei/tags/cryptodev-next-20161224' into staging (2017-01-06 15:18:09 +0000)

are available in the git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170109

for you to fetch changes up to 556899fc1965d82f5c4a3ba6a0be3b1193e2c4b2:

  hw/ssi/imx_spi.c: Remove MSGDATA register support (2017-01-09 11:50:23 +0000)

----------------------------------------------------------------
target-arm queue:
 * i2c: Allow I2C devices to NAK start events
 * hw/char: QOM'ify exynos4210_uart.c
 * clean up and refactor virt-acpi-build.c
 * virt-acpi-build: Don't incorrectly claim architectural timer
   to be edge-triggered
 * m25p80: Don't let rogue SPI controllers cause buffer overruns
 * imx_spi: Remove broken MSGDATA register support

----------------------------------------------------------------
Andrew Jones (14):
      hw/arm/virt-acpi-build: add all missing cpu_to_le's
      hw/arm/virt-acpi-build: name GIC CPU Interface Structure appropriately
      hw/arm/virt-acpi-build: gtdt: improve flag naming
      hw/arm/virt-acpi-build: fadt: improve flag naming
      hw/arm/virt: parameter passing cleanups
      hw/arm/virt: use VirtMachineState.gic_version
      hw/arm/virt: eliminate struct VirtGuestInfoState
      hw/arm/virt: remove include/hw/arm/virt-acpi-build.h
      hw/arm/virt: move VirtMachineState/Class to virt.h
      hw/arm/virt: pass VirtMachineState instead of VirtGuestInfo
      hw/arm/virt-acpi-build: remove redundant members from VirtGuestInfo
      hw/arm/virt-acpi-build: don't save VirtGuestInfo on AcpiBuildState
      hw/arm/virt: remove VirtGuestInfo
      hw/arm/virt-acpi-build: Don't incorrectly claim architectural timer to be edge-triggered

Corey Minyard (1):
      i2c: Allow I2C devices to NAK start events

Jean-Christophe Dubois (2):
      m25p80: don't let rogue SPI controllers cause buffer overruns
      hw/ssi/imx_spi.c: Remove MSGDATA register support

Peter Maydell (3):
      hw/arm/virt: Merge VirtBoardInfo and VirtMachineState
      hw/arm/virt: Rename 'vbi' variables to 'vms'
      hw/arm/virt: Don't incorrectly claim architectural timer to be edge-triggered

xiaoqiang zhao (1):
      hw/char: QOM'ify exynos4210_uart.c

 include/hw/acpi/acpi-defs.h      |  33 +-
 include/hw/arm/virt-acpi-build.h |  47 ---
 include/hw/arm/virt.h            |  41 ++-
 include/hw/i2c/i2c.h             |  16 +-
 hw/arm/pxa2xx.c                  |   4 +-
 hw/arm/tosa.c                    |   4 +-
 hw/arm/virt-acpi-build.c         | 134 ++++----
 hw/arm/virt.c                    | 691 ++++++++++++++++++---------------------
 hw/arm/z2.c                      |   4 +-
 hw/audio/wm8750.c                |   4 +-
 hw/block/m25p80.c                |  29 +-
 hw/char/exynos4210_uart.c        |  16 +-
 hw/display/ssd0303.c             |   4 +-
 hw/gpio/max7310.c                |   4 +-
 hw/i2c/core.c                    |  31 +-
 hw/i2c/i2c-ddc.c                 |   4 +-
 hw/i2c/smbus.c                   |  13 +-
 hw/input/lm832x.c                |   4 +-
 hw/misc/tmp105.c                 |   3 +-
 hw/ssi/imx_spi.c                 |  11 +-
 hw/timer/ds1338.c                |   4 +-
 hw/timer/twl92230.c              |   4 +-
 MAINTAINERS                      |   2 -
 23 files changed, 572 insertions(+), 535 deletions(-)
 delete mode 100644 include/hw/arm/virt-acpi-build.h

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

* Re: [Qemu-devel] [PULL 00/21] target-arm queue
  2015-05-18 19:15 Peter Maydell
@ 2015-05-19  7:57 ` Peter Maydell
  0 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2015-05-19  7:57 UTC (permalink / raw)
  To: QEMU Developers

On 18 May 2015 at 20:15, Peter Maydell <peter.maydell@linaro.org> wrote:
> target-arm queue: mostly the new Xilinx board, plus a handful
> of other minor things.
>
> -- PMM
>
>
> The following changes since commit 385057cbec9b4a0eb6150330c572e875ed714965:
>
>   Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2015-05-15' into staging (2015-05-15 17:51:20 +0100)
>
> are available in the git repository at:
>
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20150518-3
>
> for you to fetch changes up to 18084b2f71b22b3ec3bf4828b8cb83d1d39e8502:
>
>   target-arm: Remove unneeded '+' (2015-05-18 20:04:19 +0100)
>
> ----------------------------------------------------------------
> target-arm:
>  * New board model: xlnx-ep108
>  * Some more preparation for AArch64 EL2/EL3
>  * Fix bugs in access checking for generic counter registers
>  * Remove a stray '+' sign
>
> ----------------------------------------------------------------

Applied, thanks.

-- PMM

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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2015-05-18 19:15 Peter Maydell
  2015-05-19  7:57 ` Peter Maydell
  0 siblings, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2015-05-18 19:15 UTC (permalink / raw)
  To: qemu-devel

target-arm queue: mostly the new Xilinx board, plus a handful
of other minor things.

-- PMM


The following changes since commit 385057cbec9b4a0eb6150330c572e875ed714965:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2015-05-15' into staging (2015-05-15 17:51:20 +0100)

are available in the git repository at:


  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20150518-3

for you to fetch changes up to 18084b2f71b22b3ec3bf4828b8cb83d1d39e8502:

  target-arm: Remove unneeded '+' (2015-05-18 20:04:19 +0100)

----------------------------------------------------------------
target-arm:
 * New board model: xlnx-ep108
 * Some more preparation for AArch64 EL2/EL3
 * Fix bugs in access checking for generic counter registers
 * Remove a stray '+' sign

----------------------------------------------------------------
Edgar E. Iglesias (3):
      target-arm: Correct accessfn for CNTP_{CT}VAL_EL0
      target-arm: Correct accessfn for CNTV_TVAL_EL0
      target-arm: Remove unneeded '+'

Greg Bellows (3):
      target-arm: Add TTBR regime function and use
      target-arm: Add EL3 and EL2 TCR checking
      target-arm: Add WFx syndrome function

Peter Crosthwaite (14):
      target-arm: cpu64: generalise name of A57 regs
      target-arm: cpu64: Add support for Cortex-A53
      arm: Introduce Xilinx ZynqMP SoC
      arm: xlnx-zynqmp: Add GIC
      arm: xlnx-zynqmp: Connect CPU Timers to GIC
      net: cadence_gem: Clean up variable names
      net: cadence_gem: Split state struct and type into header
      arm: xlnx-zynqmp: Add GEM support
      char: cadence_uart: Clean up variable names
      char: cadence_uart: Split state struct and type into header
      arm: xlnx-zynqmp: Add UART support
      arm: Add xlnx-ep108 machine
      arm: xlnx-ep108: Add external RAM
      arm: xlnx-ep108: Add bootloading

Timothy Baldwin (1):
      linux-user/arm: Correct TARGET_NR_timerfd to TARGET_NR_timerfd_create

 default-configs/aarch64-softmmu.mak |   2 +-
 hw/arm/Makefile.objs                |   1 +
 hw/arm/xlnx-ep108.c                 |  82 ++++++++++++++
 hw/arm/xlnx-zynqmp.c                | 211 ++++++++++++++++++++++++++++++++++++
 hw/char/cadence_uart.c              | 115 ++++++++------------
 hw/net/cadence_gem.c                |  95 +++++-----------
 include/hw/arm/xlnx-zynqmp.h        |  58 ++++++++++
 include/hw/char/cadence_uart.h      |  53 +++++++++
 include/hw/net/cadence_gem.h        |  73 +++++++++++++
 linux-user/arm/syscall_nr.h         |   2 +-
 target-arm/cpu64.c                  |  61 ++++++++++-
 target-arm/helper.c                 |  75 +++++++++----
 target-arm/internals.h              |   6 +
 13 files changed, 671 insertions(+), 163 deletions(-)
 create mode 100644 hw/arm/xlnx-ep108.c
 create mode 100644 hw/arm/xlnx-zynqmp.c
 create mode 100644 include/hw/arm/xlnx-zynqmp.h
 create mode 100644 include/hw/char/cadence_uart.h
 create mode 100644 include/hw/net/cadence_gem.h

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

* [Qemu-devel] [PULL 00/21] target-arm queue
@ 2013-08-20 14:07 Peter Maydell
  0 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2013-08-20 14:07 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl, Anthony Liguori; +Cc: qemu-devel, Paul Brook

Hi; this is my target-arm queue. Contents:
 * my 'get rid of arm_pic' series
 * generic timer support for A15
 * a few other minor fixes

To avoid potential conflicts between a target-arm pullreq
and an arm-devs pullreq, I've just put all these ARM related
patches in the same tree even though a few of them could
strictly speaking have gone into an arm-devs tree. (I'd
actually prefer to combine target-arm.next and arm-devs.next
into a single tree in future, since I think some of the admin
reasons for the original split have now gone away. Let me know
if this is going to be a problem and I'll maintain the split.)

Please pull.

thanks
--PMM


The following changes since commit f202039811d8746b0586d2fd5f61de6c8cf68056:

  Open up 1.7 development branch (2013-08-15 15:41:13 -0500)

are available in the git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20130820

for you to fetch changes up to 230058106ab26de9b876158dbe27d60719f01f51:

  hw/timer/imx_epit: Simplify and fix imx_epit implementation (2013-08-20 14:54:32 +0100)

----------------------------------------------------------------
target-arm queue

----------------------------------------------------------------
Peter Chubb (1):
      hw/timer/imx_epit: Simplify and fix imx_epit implementation

Peter Maydell (20):
      target-arm: Implement 'int' loglevel
      target-arm: Make IRQ and FIQ gpio lines on the CPU object
      hw/arm/armv7m: Don't use arm_pic_init_cpu()
      hw/arm/exynos4210: Don't use arm_pic_init_cpu()
      hw/arm/highbank: Don't use arm_pic_init_cpu()
      hw/arm/integratorcp: Don't use arm_pic_init_cpu()
      hw/arm/kzm: Don't use arm_pic_init_cpu()
      hw/arm/musicpal: Don't use arm_pic_init_cpu()
      hw/arm/omap*: Don't use arm_pic_init_cpu()
      hw/arm/realview: Don't use arm_pic_init_cpu()
      hw/arm/strongarm: Don't use arm_pic_init_cpu()
      hw/arm/versatilepb: Don't use arm_pic_init_cpu()
      hw/arm/vexpress: Don't use arm_pic_init_cpu()
      hw/arm/xilinx_zynq: Don't use arm_pic_init_cpu()
      hw/arm/pic_cpu: Remove the now-unneeded arm_pic_init_cpu()
      target-arm: Allow raw_read() and raw_write() to handle 64 bit regs
      target-arm: Support coprocessor registers which do I/O
      target-arm: Implement the generic timer
      hw/cpu/a15mpcore: Wire generic timer outputs to GIC inputs
      default-configs: Fix A9MP and A15MP config names

 default-configs/arm-softmmu.mak |    4 +-
 hw/arm/Makefile.objs            |    2 +-
 hw/arm/armv7m.c                 |    5 +-
 hw/arm/exynos4210.c             |   16 +-
 hw/arm/highbank.c               |    4 +-
 hw/arm/integratorcp.c           |    7 +-
 hw/arm/kzm.c                    |    8 +-
 hw/arm/musicpal.c               |    4 +-
 hw/arm/omap1.c                  |    8 +-
 hw/arm/omap2.c                  |    8 +-
 hw/arm/pic_cpu.c                |   68 ---------
 hw/arm/realview.c               |    4 +-
 hw/arm/strongarm.c              |    6 +-
 hw/arm/versatilepb.c            |    7 +-
 hw/arm/vexpress.c               |    8 +-
 hw/arm/xilinx_zynq.c            |    7 +-
 hw/cpu/Makefile.objs            |    4 +-
 hw/cpu/a15mpcore.c              |   18 +++
 hw/timer/imx_epit.c             |   94 +++++-------
 include/hw/arm/arm.h            |    5 -
 target-arm/cpu-qom.h            |    9 ++
 target-arm/cpu.c                |   67 +++++++++
 target-arm/cpu.h                |   27 +++-
 target-arm/helper.c             |  310 ++++++++++++++++++++++++++++++++++++++-
 target-arm/machine.c            |    8 +-
 target-arm/translate.c          |   16 +-
 26 files changed, 514 insertions(+), 210 deletions(-)
 delete mode 100644 hw/arm/pic_cpu.c

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

end of thread, other threads:[~2019-09-04 13:46 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-16 17:18 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 01/21] loader: Fix incorrect parameter name in load_image_mr() macro Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 02/21] target-arm: Implement MRS (banked) and MSR (banked) instructions Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 03/21] target-arm: Fix translation level on early translation faults Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 04/21] arm: virt: Add an abstract ARM virt machine type Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 05/21] arm: virt: Move machine class init code to the abstract " Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 06/21] i.MX: Allow GPT timer to rollover Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 07/21] i.MX: Rename CCM NOCLK to CLK_NONE for naming consistency Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 08/21] i.MX: Remove CCM useless clock computation handling Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 09/21] i.MX: Add the CLK_IPG_HIGH clock Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 10/21] i.MX: Add i.MX6 CCM and ANALOG device Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 11/21] i.MX: Add missing descriptions in devices Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 12/21] hw/timer: Add ASPEED timer device model Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 13/21] hw/intc: Add (new) ASPEED VIC " Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 14/21] hw/arm: Add ASPEED AST2400 SoC model Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 15/21] hw/arm: Add palmetto-bmc machine Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 16/21] bcm2835_peripherals: enable sdhci pending-insert quirk for raspberry pi Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 17/21] bcm2835_aux: add emulation of BCM2835 AUX (aka UART1) block Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 18/21] bcm2835_fb: add framebuffer device for Raspberry Pi Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 19/21] bcm2835_property: implement framebuffer control/configuration properties Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 20/21] bcm2835_dma: add emulation of Raspberry Pi DMA controller Peter Maydell
2016-03-16 17:18 ` [Qemu-devel] [PULL 21/21] sd: Fix "info qtree" on boards with SD cards Peter Maydell
2016-03-16 17:42 ` [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
2016-03-16 18:19 ` Peter Maydell
  -- strict thread matches above, loose matches on Subject: below --
2019-09-03 15:36 Peter Maydell
2019-09-04 13:44 ` Peter Maydell
2019-02-21 18:57 Peter Maydell
2019-02-22 11:24 ` Peter Maydell
2018-05-10 17:44 Peter Maydell
2018-05-10 18:06 ` no-reply
2018-05-14  8:46 ` Peter Maydell
2018-02-15 13:56 Peter Maydell
2018-01-25 13:43 Peter Maydell
2018-01-25 14:18 ` no-reply
2018-01-25 18:06 ` Peter Maydell
2017-02-28 17:15 Peter Maydell
2017-03-01 19:28 ` Peter Maydell
2017-01-09 11:53 Peter Maydell
2017-01-09 13:44 ` Peter Maydell
2015-05-18 19:15 Peter Maydell
2015-05-19  7:57 ` Peter Maydell
2013-08-20 14:07 Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.