All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/36] target-arm queue
@ 2017-01-19 14:09 Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 01/36] arm: Uniquely name imx25 I2C buses Peter Maydell
                   ` (35 more replies)
  0 siblings, 36 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

ARM queue -- the big bit here is the virtualization
stuff for the GIC and correspondingly enabling it in
the virt board.

thanks
-- PMM

The following changes since commit ab4b92760498e097ff668f0e9c83aa87a2ec1128:

  Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging (2017-01-17 16:54:09 +0000)

are available in the git repository at:

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

for you to fetch changes up to 245c8cbc4e4f0f8b6c3dfaab2090d1d55f94d360:

  hw/arm/virt: Add board property to enable EL2 (2017-01-19 13:40:23 +0000)

----------------------------------------------------------------
target-arm queue:
 * support virtualization in GICv3
 * enable EL2 in AArch64 CPU models
 * allow EL2 to be enabled on 'virt' board via -machine virtualization=on
 * aspeed: SMC improvements
 * m25p80: support die erase command
 * m25p80: Add Quad Page Program 4byte
 * m25p80: Improve 1GiB Micron flash definition
 * arm: Uniquely name imx25 I2C buses

----------------------------------------------------------------
Alastair D'Silva (1):
      arm: Uniquely name imx25 I2C buses.

Andrew Jones (1):
      hw/arm/virt-acpi-build: use SMC if booting in EL2

Ard Biesheuvel (1):
      hw/arm/virt-acpi - reserve ECAM space as PNP0C02 device

Cédric Le Goater (10):
      aspeed/smc: remove call to reset in realize function
      aspeed/smc: remove call to aspeed_smc_update_cs() in reset function
      aspeed/smc: rework the prototype of the AspeedSMCFlash helper routines
      aspeed/smc: autostrap CE0/1 configuration
      aspeed/smc: unfold the AspeedSMCController array
      aspeed/smc: adjust the size of the register region
      aspeed/smc: handle SPI flash Command mode
      aspeed/smc: reset flash after each test
      aspeed/smc: extend tests for Command mode
      aspeed: use first FMC flash as a boot ROM

Marcin Krzeminski (3):
      block: m25p80: Add Quad Page Program 4byte
      block: m25p80: Introduce die erase command
      block: m25p80: Improve 1GiB Micron flash definition

Peter Maydell (19):
      target/arm: Handle VIRQ and VFIQ in arm_cpu_do_interrupt_aarch32()
      target/arm: Implement DBGVCR32_EL2 system register
      hw/intc/arm_gicv3: Add external IRQ lines for VIRQ and VFIQ
      hw/intc/arm_gic: Add external IRQ lines for VIRQ and VFIQ
      target-arm: Expose output GPIO line for VCPU maintenance interrupt
      hw/arm/virt: Wire VIRQ, VFIQ, maintenance irq lines from GIC to CPU
      target-arm: Add ARMCPU fields for GIC CPU i/f config
      hw/intc/gicv3: Add defines for ICH system register fields
      hw/intc/gicv3: Add data fields for virtualization support
      hw/intc/arm_gicv3: Add accessors for ICH_ system registers
      hw/intc/arm_gicv3: Implement ICV_ registers which are just accessors
      hw/intc/arm_gicv3: Implement ICV_ HPPIR, DIR and RPR registers
      hw/intc/arm_gicv3: Implement ICV_ registers EOIR and IAR
      hw/intc/arm_gicv3: Implement gicv3_cpuif_virt_update()
      hw/intc/arm_gicv3: Implement EL2 traps for CPU i/f regs
      hw/arm/virt: Support using SMC for PSCI
      target/arm/psci.c: If EL2 implemented, start CPUs in EL2
      target-arm: Enable EL2 feature bit on A53 and A57
      hw/arm/virt: Add board property to enable EL2

Shannon Zhao (1):
      arm: virt: Fix segmentation fault when specifying an unsupported CPU

 hw/intc/gicv3_internal.h           |   79 +++
 include/hw/arm/virt.h              |    5 +-
 include/hw/intc/arm_gic_common.h   |    2 +
 include/hw/intc/arm_gicv3_common.h |   21 +
 include/hw/ssi/aspeed_smc.h        |    4 +-
 target/arm/cpu.h                   |    9 +
 hw/arm/aspeed.c                    |   41 ++
 hw/arm/imx25_pdk.c                 |    2 +-
 hw/arm/virt-acpi-build.c           |   36 +-
 hw/arm/virt.c                      |   88 ++-
 hw/arm/xlnx-zynqmp.c               |    2 +
 hw/block/m25p80.c                  |   51 +-
 hw/i2c/imx_i2c.c                   |    2 +-
 hw/intc/arm_gic_common.c           |    6 +
 hw/intc/arm_gicv3_common.c         |   31 +
 hw/intc/arm_gicv3_cpuif.c          | 1351 +++++++++++++++++++++++++++++++++++-
 hw/ssi/aspeed_smc.c                |  330 +++++++--
 target/arm/cpu.c                   |   15 +
 target/arm/cpu64.c                 |    8 +
 target/arm/helper.c                |   21 +
 target/arm/psci.c                  |   25 +-
 tests/m25p80-test.c                |  133 ++++
 hw/intc/trace-events               |   33 +
 23 files changed, 2154 insertions(+), 141 deletions(-)

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

* [Qemu-devel] [PULL 01/36] arm: Uniquely name imx25 I2C buses.
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 02/36] block: m25p80: Add Quad Page Program 4byte Peter Maydell
                   ` (34 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Alastair D'Silva <alastair@d-silva.org>

The imx25 chip provides 3 i2c buses, but they have all been named
"i2c", which makes it difficult to predict which bus a device will
be connected to when specified on the command line.

This patch addresses the issue by naming the buses uniquely:
  i2c-bus.0 i2c-bus.1 i2c-bus.2

Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
Message-id: 20170105043430.3176-2-alastair@au1.ibm.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/imx25_pdk.c | 2 +-
 hw/i2c/imx_i2c.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
index 025b608..44e741f 100644
--- a/hw/arm/imx25_pdk.c
+++ b/hw/arm/imx25_pdk.c
@@ -139,7 +139,7 @@ static void imx25_pdk_init(MachineState *machine)
          * of simple qtest. See "make check" for details.
          */
         i2c_create_slave((I2CBus *)qdev_get_child_bus(DEVICE(&s->soc.i2c[0]),
-                                                      "i2c"),
+                                                      "i2c-bus.0"),
                          "ds1338", 0x68);
     }
 }
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
index 37e5a62..6c81b98 100644
--- a/hw/i2c/imx_i2c.c
+++ b/hw/i2c/imx_i2c.c
@@ -310,7 +310,7 @@ static void imx_i2c_realize(DeviceState *dev, Error **errp)
                           IMX_I2C_MEM_SIZE);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
-    s->bus = i2c_init_bus(DEVICE(dev), "i2c");
+    s->bus = i2c_init_bus(DEVICE(dev), NULL);
 }
 
 static void imx_i2c_class_init(ObjectClass *klass, void *data)
-- 
2.7.4

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

* [Qemu-devel] [PULL 02/36] block: m25p80: Add Quad Page Program 4byte
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 01/36] arm: Uniquely name imx25 I2C buses Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 03/36] block: m25p80: Introduce die erase command Peter Maydell
                   ` (33 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Marcin Krzeminski <mar.krzeminski@gmail.com>

Some flash chips have additional page program opcode that
takes only 4 byte address. This commit adds support
for such command in Qemu.

Signed-off-by: Marcin Krzeminski <mar.krzeminski@gmail.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 20170108083854.5006-2-mar.krzeminski@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/block/m25p80.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 4c5f8c3..4ad67ac 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -327,6 +327,7 @@ typedef enum {
     PP4_4 = 0x3e,
     DPP = 0xa2,
     QPP = 0x32,
+    QPP_4 = 0x34,
 
     ERASE_4K = 0x20,
     ERASE4_4K = 0x21,
@@ -577,6 +578,7 @@ static inline int get_addr_length(Flash *s)
    switch (s->cmd_in_progress) {
    case PP4:
    case PP4_4:
+   case QPP_4:
    case READ4:
    case QIOR4:
    case ERASE4_4K:
@@ -610,6 +612,7 @@ static void complete_collecting_data(Flash *s)
     switch (s->cmd_in_progress) {
     case DPP:
     case QPP:
+    case QPP_4:
     case PP:
     case PP4:
     case PP4_4:
@@ -877,6 +880,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
     case READ4:
     case DPP:
     case QPP:
+    case QPP_4:
     case PP:
     case PP4:
     case PP4_4:
-- 
2.7.4

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

* [Qemu-devel] [PULL 03/36] block: m25p80: Introduce die erase command
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 01/36] arm: Uniquely name imx25 I2C buses Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 02/36] block: m25p80: Add Quad Page Program 4byte Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 04/36] block: m25p80: Improve 1GiB Micron flash definition Peter Maydell
                   ` (32 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Marcin Krzeminski <mar.krzeminski@gmail.com>

Modern big flash NOR devices consist of more than one die.
Some of them do not support chip erase and instead have a die
erase command that can erase one die only. This commit adds
support for defining the number of dies in the chip, and adds
support for die erase command.

The NOR flash model is not strict, so no option to
disable chip erase has been added.

Signed-off-by: Marcin Krzeminski <mar.krzeminski@gmail.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 20170108083854.5006-3-mar.krzeminski@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/block/m25p80.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 4ad67ac..74c6e39 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -74,6 +74,12 @@ typedef struct FlashPartInfo {
     uint32_t n_sectors;
     uint32_t page_size;
     uint16_t flags;
+    /*
+     * Big sized spi nor are often stacked devices, thus sometime
+     * replace chip erase with die erase.
+     * This field inform how many die is in the chip.
+     */
+    uint8_t die_cnt;
 } FlashPartInfo;
 
 /* adapted from linux */
@@ -91,7 +97,8 @@ typedef struct FlashPartInfo {
     .sector_size = (_sector_size),\
     .n_sectors = (_n_sectors),\
     .page_size = 256,\
-    .flags = (_flags),
+    .flags = (_flags),\
+    .die_cnt = 0
 
 #define INFO6(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\
     .part_name = _part_name,\
@@ -108,6 +115,24 @@ typedef struct FlashPartInfo {
     .n_sectors = (_n_sectors),\
     .page_size = 256,\
     .flags = (_flags),\
+    .die_cnt = 0
+
+#define INFO_STACKED(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors,\
+                    _flags, _die_cnt)\
+    .part_name = _part_name,\
+    .id = {\
+        ((_jedec_id) >> 16) & 0xff,\
+        ((_jedec_id) >> 8) & 0xff,\
+        (_jedec_id) & 0xff,\
+        ((_ext_id) >> 8) & 0xff,\
+        (_ext_id) & 0xff,\
+          },\
+    .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),\
+    .sector_size = (_sector_size),\
+    .n_sectors = (_n_sectors),\
+    .page_size = 256,\
+    .flags = (_flags),\
+    .die_cnt = _die_cnt
 
 #define JEDEC_NUMONYX 0x20
 #define JEDEC_WINBOND 0xEF
@@ -360,6 +385,8 @@ typedef enum {
 
     REVCR = 0x65,
     WEVCR = 0x61,
+
+    DIE_ERASE = 0xC4,
 } FlashCMD;
 
 typedef enum {
@@ -517,6 +544,16 @@ static void flash_erase(Flash *s, int offset, FlashCMD cmd)
     case BULK_ERASE:
         len = s->size;
         break;
+    case DIE_ERASE:
+        if (s->pi->die_cnt) {
+            len = s->size / s->pi->die_cnt;
+            offset = offset & (~(len - 1));
+        } else {
+            qemu_log_mask(LOG_GUEST_ERROR, "M25P80: die erase is not supported"
+                          " by device\n");
+            return;
+        }
+        break;
     default:
         abort();
     }
@@ -638,6 +675,7 @@ static void complete_collecting_data(Flash *s)
     case ERASE4_32K:
     case ERASE_SECTOR:
     case ERASE4_SECTOR:
+    case DIE_ERASE:
         flash_erase(s, s->cur_addr, s->cmd_in_progress);
         break;
     case WRSR:
@@ -884,6 +922,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
     case PP:
     case PP4:
     case PP4_4:
+    case DIE_ERASE:
         s->needed_bytes = get_addr_length(s);
         s->pos = 0;
         s->len = 0;
-- 
2.7.4

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

* [Qemu-devel] [PULL 04/36] block: m25p80: Improve 1GiB Micron flash definition
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (2 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 03/36] block: m25p80: Introduce die erase command Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 05/36] target/arm: Handle VIRQ and VFIQ in arm_cpu_do_interrupt_aarch32() Peter Maydell
                   ` (31 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Marcin Krzeminski <mar.krzeminski@gmail.com>

n25q00 and mt25q01 devices share the same JEDEC ID. The difference
between those two devices is number of dies and one bit in extended
JEDEC bytes. This commit adds proper entry for both devices by
introduction the number of dies and and new 25q00 entries.

Signed-off-by: Marcin Krzeminski <mar.krzeminski@gmail.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 20170108083854.5006-4-mar.krzeminski@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/block/m25p80.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 74c6e39..e904514 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -243,8 +243,10 @@ static const FlashPartInfo known_devices[] = {
     { INFO("n25q128",     0x20ba18,      0,  64 << 10, 256, 0) },
     { INFO("n25q256a",    0x20ba19,      0,  64 << 10, 512, ER_4K) },
     { INFO("n25q512a",    0x20ba20,      0,  64 << 10, 1024, ER_4K) },
-    { INFO("mt25ql01g",   0x20ba21,      0,  64 << 10, 2048, ER_4K) },
-    { INFO("mt25qu01g",   0x20bb21,      0,  64 << 10, 2048, ER_4K) },
+    { INFO_STACKED("n25q00",    0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
+    { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
+    { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
+    { INFO_STACKED("mt25qu01g", 0x20bb21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
 
     /* Spansion -- single (large) sector size only, at least
      * for the chips listed here (without boot sectors).
-- 
2.7.4

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

* [Qemu-devel] [PULL 05/36] target/arm: Handle VIRQ and VFIQ in arm_cpu_do_interrupt_aarch32()
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (3 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 04/36] block: m25p80: Improve 1GiB Micron flash definition Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 06/36] target/arm: Implement DBGVCR32_EL2 system register Peter Maydell
                   ` (30 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

To run a VM in 32-bit EL1 our AArch32 interrupt handling code
needs to be able to cope with VIRQ and VFIQ exceptions.
These behave like IRQ and FIQ except that we don't need to try
to route them to Monitor mode.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 target/arm/helper.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index b3875c7..ba72ebb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6399,6 +6399,20 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
         }
         offset = 4;
         break;
+    case EXCP_VIRQ:
+        new_mode = ARM_CPU_MODE_IRQ;
+        addr = 0x18;
+        /* Disable IRQ and imprecise data aborts.  */
+        mask = CPSR_A | CPSR_I;
+        offset = 4;
+        break;
+    case EXCP_VFIQ:
+        new_mode = ARM_CPU_MODE_FIQ;
+        addr = 0x1c;
+        /* Disable FIQ, IRQ and imprecise data aborts.  */
+        mask = CPSR_A | CPSR_I | CPSR_F;
+        offset = 4;
+        break;
     case EXCP_SMC:
         new_mode = ARM_CPU_MODE_MON;
         addr = 0x08;
-- 
2.7.4

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

* [Qemu-devel] [PULL 06/36] target/arm: Implement DBGVCR32_EL2 system register
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (4 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 05/36] target/arm: Handle VIRQ and VFIQ in arm_cpu_do_interrupt_aarch32() Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 07/36] aspeed/smc: remove call to reset in realize function Peter Maydell
                   ` (29 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

The DBGVCR_EL2 system register is needed to run a 32-bit
EL1 guest under a Linux EL2 64-bit hypervisor. Its only
purpose is to provide AArch64 with access to the state of
the DBGVCR AArch32 register. Since we only have a dummy
DBGVCR, implement a corresponding dummy DBGVCR32_EL2.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 target/arm/helper.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index ba72ebb..7111c8c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4066,6 +4066,13 @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
       .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
       .access = PL1_RW, .accessfn = access_tda,
       .type = ARM_CP_NOP },
+    /* Dummy DBGVCR32_EL2 (which is only for a 64-bit hypervisor
+     * to save and restore a 32-bit guest's DBGVCR)
+     */
+    { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
+      .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
+      .access = PL2_RW, .accessfn = access_tda,
+      .type = ARM_CP_NOP },
     /* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
      * Channel but Linux may try to access this register. The 32-bit
      * alias is DBGDCCINT.
-- 
2.7.4

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

* [Qemu-devel] [PULL 07/36] aspeed/smc: remove call to reset in realize function
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (5 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 06/36] target/arm: Implement DBGVCR32_EL2 system register Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 08/36] aspeed/smc: remove call to aspeed_smc_update_cs() in reset function Peter Maydell
                   ` (28 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

This is useless as reset will be called later on.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Acked-by: Marcin Krzemiński <mar.krzeminski@gmail.com>
Message-id: 1483979087-32663-2-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/aspeed_smc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 78f5aed..8a7217d 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -541,8 +541,6 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
         sysbus_init_irq(sbd, &s->cs_lines[i]);
     }
 
-    aspeed_smc_reset(dev);
-
     /* The memory region for the controller registers */
     memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
                           s->ctrl->name, ASPEED_SMC_R_MAX * 4);
-- 
2.7.4

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

* [Qemu-devel] [PULL 08/36] aspeed/smc: remove call to aspeed_smc_update_cs() in reset function
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (6 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 07/36] aspeed/smc: remove call to reset in realize function Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 09/36] aspeed/smc: rework the prototype of the AspeedSMCFlash helper routines Peter Maydell
                   ` (27 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

Instead, we can simply set the irq level when unselecting the slave
devices. This change prepares ground for a subsequent cleanup of the
aspeed_smc_update_cs() routine which uselessly loops on all slaves to
update their status.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 1483979087-32663-3-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/aspeed_smc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 8a7217d..205c0ab 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -424,6 +424,7 @@ static void aspeed_smc_reset(DeviceState *d)
     /* Unselect all slaves */
     for (i = 0; i < s->num_cs; ++i) {
         s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
+        qemu_set_irq(s->cs_lines[i], true);
     }
 
     /* setup default segment register values for all */
@@ -431,8 +432,6 @@ static void aspeed_smc_reset(DeviceState *d)
         s->regs[R_SEG_ADDR0 + i] =
             aspeed_smc_segment_to_reg(&s->ctrl->segments[i]);
     }
-
-    aspeed_smc_update_cs(s);
 }
 
 static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
-- 
2.7.4

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

* [Qemu-devel] [PULL 09/36] aspeed/smc: rework the prototype of the AspeedSMCFlash helper routines
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (7 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 08/36] aspeed/smc: remove call to aspeed_smc_update_cs() in reset function Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 10/36] aspeed/smc: autostrap CE0/1 configuration Peter Maydell
                   ` (26 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

Change the routines prototype to use a 'AspeedSMCFlash *' instead of
'AspeedSMCState *'. The result will help in making future changes
clearer.

Also change aspeed_smc_update_cs() which uselessly loops on all slave
devices to update their status.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1483979087-32663-4-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/aspeed_smc.c | 39 ++++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 205c0ab..9b31d5d 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -328,19 +328,23 @@ static const MemoryRegionOps aspeed_smc_flash_default_ops = {
     },
 };
 
-static inline int aspeed_smc_flash_mode(const AspeedSMCState *s, int cs)
+static inline int aspeed_smc_flash_mode(const AspeedSMCFlash *fl)
 {
-    return s->regs[s->r_ctrl0 + cs] & CTRL_CMD_MODE_MASK;
+    const AspeedSMCState *s = fl->controller;
+
+    return s->regs[s->r_ctrl0 + fl->id] & CTRL_CMD_MODE_MASK;
 }
 
-static inline bool aspeed_smc_is_usermode(const AspeedSMCState *s, int cs)
+static inline bool aspeed_smc_is_usermode(const AspeedSMCFlash *fl)
 {
-    return aspeed_smc_flash_mode(s, cs) == CTRL_USERMODE;
+    return aspeed_smc_flash_mode(fl) == CTRL_USERMODE;
 }
 
-static inline bool aspeed_smc_is_writable(const AspeedSMCState *s, int cs)
+static inline bool aspeed_smc_is_writable(const AspeedSMCFlash *fl)
 {
-    return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + cs));
+    const AspeedSMCState *s = fl->controller;
+
+    return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
 }
 
 static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
@@ -350,7 +354,7 @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
     uint64_t ret = 0;
     int i;
 
-    if (aspeed_smc_is_usermode(s, fl->id)) {
+    if (aspeed_smc_is_usermode(fl)) {
         for (i = 0; i < size; i++) {
             ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
         }
@@ -370,13 +374,13 @@ static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
     const AspeedSMCState *s = fl->controller;
     int i;
 
-    if (!aspeed_smc_is_writable(s, fl->id)) {
+    if (!aspeed_smc_is_writable(fl)) {
         qemu_log_mask(LOG_GUEST_ERROR, "%s: flash is not writable at 0x%"
                       HWADDR_PRIx "\n", __func__, addr);
         return;
     }
 
-    if (!aspeed_smc_is_usermode(s, fl->id)) {
+    if (!aspeed_smc_is_usermode(fl)) {
         qemu_log_mask(LOG_UNIMP, "%s: usermode not implemented\n",
                       __func__);
         return;
@@ -397,18 +401,18 @@ static const MemoryRegionOps aspeed_smc_flash_ops = {
     },
 };
 
-static bool aspeed_smc_is_ce_stop_active(const AspeedSMCState *s, int cs)
+static inline bool aspeed_smc_is_ce_stop_active(const AspeedSMCFlash *fl)
 {
-    return s->regs[s->r_ctrl0 + cs] & CTRL_CE_STOP_ACTIVE;
+    const AspeedSMCState *s = fl->controller;
+
+    return s->regs[s->r_ctrl0 + fl->id] & CTRL_CE_STOP_ACTIVE;
 }
 
-static void aspeed_smc_update_cs(const AspeedSMCState *s)
+static void aspeed_smc_flash_update_cs(AspeedSMCFlash *fl)
 {
-    int i;
+    const AspeedSMCState *s = fl->controller;
 
-    for (i = 0; i < s->num_cs; ++i) {
-        qemu_set_irq(s->cs_lines[i], aspeed_smc_is_ce_stop_active(s, i));
-    }
+    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
 }
 
 static void aspeed_smc_reset(DeviceState *d)
@@ -481,8 +485,9 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
         addr == s->r_ce_ctrl) {
         s->regs[addr] = value;
     } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
+        int cs = addr - s->r_ctrl0;
         s->regs[addr] = value;
-        aspeed_smc_update_cs(s);
+        aspeed_smc_flash_update_cs(&s->flashes[cs]);
     } else if (addr >= R_SEG_ADDR0 &&
                addr < R_SEG_ADDR0 + s->ctrl->max_slaves) {
         int cs = addr - R_SEG_ADDR0;
-- 
2.7.4

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

* [Qemu-devel] [PULL 10/36] aspeed/smc: autostrap CE0/1 configuration
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (8 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 09/36] aspeed/smc: rework the prototype of the AspeedSMCFlash helper routines Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 11/36] aspeed/smc: unfold the AspeedSMCController array Peter Maydell
                   ` (25 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

On the AST2500 SoC, the FMC controller flash type is fixed to SPI for
CE0 and CE1 and 4BYTE mode is autodetected for CE0.

On the AST2400 SoC, the FMC controller flash type and 4BYTE mode are
strapped with register SCU70. We use the default settings from the
palmetto-bmc machine for now.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1483979087-32663-5-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/ssi/aspeed_smc.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 9b31d5d..3bd381b 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -39,11 +39,14 @@
 #define   CONF_ENABLE_W2       18
 #define   CONF_ENABLE_W1       17
 #define   CONF_ENABLE_W0       16
-#define   CONF_FLASH_TYPE4     9
-#define   CONF_FLASH_TYPE3     7
-#define   CONF_FLASH_TYPE2     5
-#define   CONF_FLASH_TYPE1     3
-#define   CONF_FLASH_TYPE0     1
+#define   CONF_FLASH_TYPE4     8
+#define   CONF_FLASH_TYPE3     6
+#define   CONF_FLASH_TYPE2     4
+#define   CONF_FLASH_TYPE1     2
+#define   CONF_FLASH_TYPE0     0
+#define      CONF_FLASH_TYPE_NOR   0x0
+#define      CONF_FLASH_TYPE_NAND  0x1
+#define      CONF_FLASH_TYPE_SPI   0x2
 
 /* CE Control Register */
 #define R_CE_CTRL            (0x04 / 4)
@@ -436,6 +439,25 @@ static void aspeed_smc_reset(DeviceState *d)
         s->regs[R_SEG_ADDR0 + i] =
             aspeed_smc_segment_to_reg(&s->ctrl->segments[i]);
     }
+
+    /* HW strapping for AST2500 FMC controllers  */
+    if (s->ctrl->segments == aspeed_segments_ast2500_fmc) {
+        /* flash type is fixed to SPI for CE0 and CE1 */
+        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
+        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
+
+        /* 4BYTE mode is autodetected for CE0. Let's force it to 1 for
+         * now */
+        s->regs[s->r_ce_ctrl] |= (1 << (CTRL_EXTENDED0));
+    }
+
+    /* HW strapping for AST2400 FMC controllers (SCU70). Let's use the
+     * configuration of the palmetto-bmc machine */
+    if (s->ctrl->segments == aspeed_segments_fmc) {
+        s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
+
+        s->regs[s->r_ce_ctrl] |= (1 << (CTRL_EXTENDED0));
+    }
 }
 
 static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
-- 
2.7.4

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

* [Qemu-devel] [PULL 11/36] aspeed/smc: unfold the AspeedSMCController array
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (9 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 10/36] aspeed/smc: autostrap CE0/1 configuration Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 12/36] aspeed/smc: adjust the size of the register region Peter Maydell
                   ` (24 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

This is getting difficult to read. Also add a 'has_dma' field for each
controller type.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1483979087-32663-6-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/ssi/aspeed_smc.h |  1 +
 hw/ssi/aspeed_smc.c         | 91 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 74 insertions(+), 18 deletions(-)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index bdfbcc0..861120b 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -44,6 +44,7 @@ typedef struct AspeedSMCController {
     const AspeedSegments *segments;
     hwaddr flash_window_base;
     uint32_t flash_window_size;
+    bool has_dma;
 } AspeedSMCController;
 
 typedef struct AspeedSMCFlash {
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 3bd381b..d8287ab 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -173,24 +173,79 @@ static const AspeedSegments aspeed_segments_ast2500_spi2[] = {
 };
 
 static const AspeedSMCController controllers[] = {
-    { "aspeed.smc.smc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 5, aspeed_segments_legacy,
-      ASPEED_SOC_SMC_FLASH_BASE, 0x6000000 },
-    { "aspeed.smc.fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 5, aspeed_segments_fmc,
-      ASPEED_SOC_FMC_FLASH_BASE, 0x10000000 },
-    { "aspeed.smc.spi", R_SPI_CONF, 0xff, R_SPI_CTRL0, R_SPI_TIMINGS,
-      SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi,
-      ASPEED_SOC_SPI_FLASH_BASE, 0x10000000 },
-    { "aspeed.smc.ast2500-fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 3, aspeed_segments_ast2500_fmc,
-      ASPEED_SOC_FMC_FLASH_BASE, 0x10000000 },
-    { "aspeed.smc.ast2500-spi1", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 2, aspeed_segments_ast2500_spi1,
-      ASPEED_SOC_SPI_FLASH_BASE, 0x8000000 },
-    { "aspeed.smc.ast2500-spi2", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
-      CONF_ENABLE_W0, 2, aspeed_segments_ast2500_spi2,
-      ASPEED_SOC_SPI2_FLASH_BASE, 0x8000000 },
+    {
+        .name              = "aspeed.smc.smc",
+        .r_conf            = R_CONF,
+        .r_ce_ctrl         = R_CE_CTRL,
+        .r_ctrl0           = R_CTRL0,
+        .r_timings         = R_TIMINGS,
+        .conf_enable_w0    = CONF_ENABLE_W0,
+        .max_slaves        = 5,
+        .segments          = aspeed_segments_legacy,
+        .flash_window_base = ASPEED_SOC_SMC_FLASH_BASE,
+        .flash_window_size = 0x6000000,
+        .has_dma           = false,
+    }, {
+        .name              = "aspeed.smc.fmc",
+        .r_conf            = R_CONF,
+        .r_ce_ctrl         = R_CE_CTRL,
+        .r_ctrl0           = R_CTRL0,
+        .r_timings         = R_TIMINGS,
+        .conf_enable_w0    = CONF_ENABLE_W0,
+        .max_slaves        = 5,
+        .segments          = aspeed_segments_fmc,
+        .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
+        .flash_window_size = 0x10000000,
+        .has_dma           = true,
+    }, {
+        .name              = "aspeed.smc.spi",
+        .r_conf            = R_SPI_CONF,
+        .r_ce_ctrl         = 0xff,
+        .r_ctrl0           = R_SPI_CTRL0,
+        .r_timings         = R_SPI_TIMINGS,
+        .conf_enable_w0    = SPI_CONF_ENABLE_W0,
+        .max_slaves        = 1,
+        .segments          = aspeed_segments_spi,
+        .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
+        .flash_window_size = 0x10000000,
+        .has_dma           = false,
+    }, {
+        .name              = "aspeed.smc.ast2500-fmc",
+        .r_conf            = R_CONF,
+        .r_ce_ctrl         = R_CE_CTRL,
+        .r_ctrl0           = R_CTRL0,
+        .r_timings         = R_TIMINGS,
+        .conf_enable_w0    = CONF_ENABLE_W0,
+        .max_slaves        = 3,
+        .segments          = aspeed_segments_ast2500_fmc,
+        .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
+        .flash_window_size = 0x10000000,
+        .has_dma           = true,
+    }, {
+        .name              = "aspeed.smc.ast2500-spi1",
+        .r_conf            = R_CONF,
+        .r_ce_ctrl         = R_CE_CTRL,
+        .r_ctrl0           = R_CTRL0,
+        .r_timings         = R_TIMINGS,
+        .conf_enable_w0    = CONF_ENABLE_W0,
+        .max_slaves        = 2,
+        .segments          = aspeed_segments_ast2500_spi1,
+        .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
+        .flash_window_size = 0x8000000,
+        .has_dma           = false,
+    }, {
+        .name              = "aspeed.smc.ast2500-spi2",
+        .r_conf            = R_CONF,
+        .r_ce_ctrl         = R_CE_CTRL,
+        .r_ctrl0           = R_CTRL0,
+        .r_timings         = R_TIMINGS,
+        .conf_enable_w0    = CONF_ENABLE_W0,
+        .max_slaves        = 2,
+        .segments          = aspeed_segments_ast2500_spi2,
+        .flash_window_base = ASPEED_SOC_SPI2_FLASH_BASE,
+        .flash_window_size = 0x8000000,
+        .has_dma           = false,
+    },
 };
 
 /*
-- 
2.7.4

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

* [Qemu-devel] [PULL 12/36] aspeed/smc: adjust the size of the register region
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (10 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 11/36] aspeed/smc: unfold the AspeedSMCController array Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 13/36] aspeed/smc: handle SPI flash Command mode Peter Maydell
                   ` (23 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

The SPI controller of the AST2400 SoC has less registers. So we can
adjust the size of the memory region holding the registers depending
on the controller type. We can also remove the guest_error logging
which is useless as the range of the region is strict enough.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Message-id: 1483979087-32663-7-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/ssi/aspeed_smc.h |  1 +
 hw/ssi/aspeed_smc.c         | 25 ++++++++++---------------
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 861120b..e811742 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -45,6 +45,7 @@ typedef struct AspeedSMCController {
     hwaddr flash_window_base;
     uint32_t flash_window_size;
     bool has_dma;
+    uint32_t nregs;
 } AspeedSMCController;
 
 typedef struct AspeedSMCFlash {
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index d8287ab..8d8a62e 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -130,6 +130,9 @@
 #define R_SPI_MISC_CTRL   (0x10 / 4)
 #define R_SPI_TIMINGS     (0x14 / 4)
 
+#define ASPEED_SMC_R_SPI_MAX (0x20 / 4)
+#define ASPEED_SMC_R_SMC_MAX (0x20 / 4)
+
 #define ASPEED_SOC_SMC_FLASH_BASE   0x10000000
 #define ASPEED_SOC_FMC_FLASH_BASE   0x20000000
 #define ASPEED_SOC_SPI_FLASH_BASE   0x30000000
@@ -185,6 +188,7 @@ static const AspeedSMCController controllers[] = {
         .flash_window_base = ASPEED_SOC_SMC_FLASH_BASE,
         .flash_window_size = 0x6000000,
         .has_dma           = false,
+        .nregs             = ASPEED_SMC_R_SMC_MAX,
     }, {
         .name              = "aspeed.smc.fmc",
         .r_conf            = R_CONF,
@@ -197,6 +201,7 @@ static const AspeedSMCController controllers[] = {
         .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
         .flash_window_size = 0x10000000,
         .has_dma           = true,
+        .nregs             = ASPEED_SMC_R_MAX,
     }, {
         .name              = "aspeed.smc.spi",
         .r_conf            = R_SPI_CONF,
@@ -209,6 +214,7 @@ static const AspeedSMCController controllers[] = {
         .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
         .flash_window_size = 0x10000000,
         .has_dma           = false,
+        .nregs             = ASPEED_SMC_R_SPI_MAX,
     }, {
         .name              = "aspeed.smc.ast2500-fmc",
         .r_conf            = R_CONF,
@@ -221,6 +227,7 @@ static const AspeedSMCController controllers[] = {
         .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
         .flash_window_size = 0x10000000,
         .has_dma           = true,
+        .nregs             = ASPEED_SMC_R_MAX,
     }, {
         .name              = "aspeed.smc.ast2500-spi1",
         .r_conf            = R_CONF,
@@ -233,6 +240,7 @@ static const AspeedSMCController controllers[] = {
         .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
         .flash_window_size = 0x8000000,
         .has_dma           = false,
+        .nregs             = ASPEED_SMC_R_MAX,
     }, {
         .name              = "aspeed.smc.ast2500-spi2",
         .r_conf            = R_CONF,
@@ -245,6 +253,7 @@ static const AspeedSMCController controllers[] = {
         .flash_window_base = ASPEED_SOC_SPI2_FLASH_BASE,
         .flash_window_size = 0x8000000,
         .has_dma           = false,
+        .nregs             = ASPEED_SMC_R_MAX,
     },
 };
 
@@ -521,13 +530,6 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
 
     addr >>= 2;
 
-    if (addr >= ARRAY_SIZE(s->regs)) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Out-of-bounds read at 0x%" HWADDR_PRIx "\n",
-                      __func__, addr);
-        return 0;
-    }
-
     if (addr == s->r_conf ||
         addr == s->r_timings ||
         addr == s->r_ce_ctrl ||
@@ -550,13 +552,6 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
 
     addr >>= 2;
 
-    if (addr >= ARRAY_SIZE(s->regs)) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Out-of-bounds write at 0x%" HWADDR_PRIx "\n",
-                      __func__, addr);
-        return;
-    }
-
     if (addr == s->r_conf ||
         addr == s->r_timings ||
         addr == s->r_ce_ctrl) {
@@ -624,7 +619,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
 
     /* The memory region for the controller registers */
     memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
-                          s->ctrl->name, ASPEED_SMC_R_MAX * 4);
+                          s->ctrl->name, s->ctrl->nregs * 4);
     sysbus_init_mmio(sbd, &s->mmio);
 
     /*
-- 
2.7.4

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

* [Qemu-devel] [PULL 13/36] aspeed/smc: handle SPI flash Command mode
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (11 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 12/36] aspeed/smc: adjust the size of the register region Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 14/36] aspeed/smc: reset flash after each test Peter Maydell
                   ` (22 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

The Aspeed SMC controllers have a mode (Command mode) in which
accesses to the flash content are no different than doing MMIOs. The
controller generates all the necessary commands to load (or store)
data in memory.

However, accesses are restricted to the segment window assigned the
the flash module by the controller. This window is defined by the
Segment Address Register.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1483979087-32663-8-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/ssi/aspeed_smc.h |   2 +-
 hw/ssi/aspeed_smc.c         | 152 ++++++++++++++++++++++++++++++++++++++------
 2 files changed, 132 insertions(+), 22 deletions(-)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index e811742..1f55731 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -49,7 +49,7 @@ typedef struct AspeedSMCController {
 } AspeedSMCController;
 
 typedef struct AspeedSMCFlash {
-    const struct AspeedSMCState *controller;
+    struct AspeedSMCState *controller;
 
     uint8_t id;
     uint32_t size;
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 8d8a62e..a0a8164 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -69,6 +69,7 @@
 #define R_CTRL0           (0x10 / 4)
 #define   CTRL_CMD_SHIFT           16
 #define   CTRL_CMD_MASK            0xff
+#define   CTRL_AST2400_SPI_4BYTE   (1 << 13)
 #define   CTRL_CE_STOP_ACTIVE      (1 << 2)
 #define   CTRL_CMD_MODE_MASK       0x3
 #define     CTRL_READMODE          0x0
@@ -138,6 +139,9 @@
 #define ASPEED_SOC_SPI_FLASH_BASE   0x30000000
 #define ASPEED_SOC_SPI2_FLASH_BASE  0x38000000
 
+/* Flash opcodes. */
+#define SPI_OP_READ       0x03    /* Read data bytes (low frequency) */
+
 /*
  * Default segments mapping addresses and size for each slave per
  * controller. These can be changed when board is initialized with the
@@ -414,21 +418,123 @@ static inline bool aspeed_smc_is_writable(const AspeedSMCFlash *fl)
     return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
 }
 
+static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
+{
+    const AspeedSMCState *s = fl->controller;
+    int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
+
+    /* In read mode, the default SPI command is READ (0x3). In other
+     * modes, the command should necessarily be defined */
+    if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
+        cmd = SPI_OP_READ;
+    }
+
+    if (!cmd) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: no command defined for mode %d\n",
+                      __func__, aspeed_smc_flash_mode(fl));
+    }
+
+    return cmd;
+}
+
+static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
+{
+    const AspeedSMCState *s = fl->controller;
+
+    if (s->ctrl->segments == aspeed_segments_spi) {
+        return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
+    } else {
+        return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->id));
+    }
+}
+
+static inline bool aspeed_smc_is_ce_stop_active(const AspeedSMCFlash *fl)
+{
+    const AspeedSMCState *s = fl->controller;
+
+    return s->regs[s->r_ctrl0 + fl->id] & CTRL_CE_STOP_ACTIVE;
+}
+
+static void aspeed_smc_flash_select(AspeedSMCFlash *fl)
+{
+    AspeedSMCState *s = fl->controller;
+
+    s->regs[s->r_ctrl0 + fl->id] &= ~CTRL_CE_STOP_ACTIVE;
+    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
+}
+
+static void aspeed_smc_flash_unselect(AspeedSMCFlash *fl)
+{
+    AspeedSMCState *s = fl->controller;
+
+    s->regs[s->r_ctrl0 + fl->id] |= CTRL_CE_STOP_ACTIVE;
+    qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
+}
+
+static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
+                                              uint32_t addr)
+{
+    const AspeedSMCState *s = fl->controller;
+    AspeedSegments seg;
+
+    aspeed_smc_reg_to_segment(s->regs[R_SEG_ADDR0 + fl->id], &seg);
+    if ((addr & (seg.size - 1)) != addr) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: invalid address 0x%08x for CS%d segment : "
+                      "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
+                      s->ctrl->name, addr, fl->id, seg.addr,
+                      seg.addr + seg.size);
+    }
+
+    addr &= seg.size - 1;
+    return addr;
+}
+
+static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
+{
+    const AspeedSMCState *s = fl->controller;
+    uint8_t cmd = aspeed_smc_flash_cmd(fl);
+
+    /* Flash access can not exceed CS segment */
+    addr = aspeed_smc_check_segment_addr(fl, addr);
+
+    ssi_transfer(s->spi, cmd);
+
+    if (aspeed_smc_flash_is_4byte(fl)) {
+        ssi_transfer(s->spi, (addr >> 24) & 0xff);
+    }
+    ssi_transfer(s->spi, (addr >> 16) & 0xff);
+    ssi_transfer(s->spi, (addr >> 8) & 0xff);
+    ssi_transfer(s->spi, (addr & 0xff));
+}
+
 static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
 {
     AspeedSMCFlash *fl = opaque;
-    const AspeedSMCState *s = fl->controller;
+    AspeedSMCState *s = fl->controller;
     uint64_t ret = 0;
     int i;
 
-    if (aspeed_smc_is_usermode(fl)) {
+    switch (aspeed_smc_flash_mode(fl)) {
+    case CTRL_USERMODE:
         for (i = 0; i < size; i++) {
             ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
         }
-    } else {
-        qemu_log_mask(LOG_UNIMP, "%s: usermode not implemented\n",
-                      __func__);
-        ret = -1;
+        break;
+    case CTRL_READMODE:
+    case CTRL_FREADMODE:
+        aspeed_smc_flash_select(fl);
+        aspeed_smc_flash_send_addr(fl, addr);
+
+        for (i = 0; i < size; i++) {
+            ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
+        }
+
+        aspeed_smc_flash_unselect(fl);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
+                      __func__, aspeed_smc_flash_mode(fl));
     }
 
     return ret;
@@ -438,7 +544,7 @@ static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
                            unsigned size)
 {
     AspeedSMCFlash *fl = opaque;
-    const AspeedSMCState *s = fl->controller;
+    AspeedSMCState *s = fl->controller;
     int i;
 
     if (!aspeed_smc_is_writable(fl)) {
@@ -447,14 +553,25 @@ static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
         return;
     }
 
-    if (!aspeed_smc_is_usermode(fl)) {
-        qemu_log_mask(LOG_UNIMP, "%s: usermode not implemented\n",
-                      __func__);
-        return;
-    }
+    switch (aspeed_smc_flash_mode(fl)) {
+    case CTRL_USERMODE:
+        for (i = 0; i < size; i++) {
+            ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
+        }
+        break;
+    case CTRL_WRITEMODE:
+        aspeed_smc_flash_select(fl);
+        aspeed_smc_flash_send_addr(fl, addr);
+
+        for (i = 0; i < size; i++) {
+            ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
+        }
 
-    for (i = 0; i < size; i++) {
-        ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
+        aspeed_smc_flash_unselect(fl);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
+                      __func__, aspeed_smc_flash_mode(fl));
     }
 }
 
@@ -468,13 +585,6 @@ static const MemoryRegionOps aspeed_smc_flash_ops = {
     },
 };
 
-static inline bool aspeed_smc_is_ce_stop_active(const AspeedSMCFlash *fl)
-{
-    const AspeedSMCState *s = fl->controller;
-
-    return s->regs[s->r_ctrl0 + fl->id] & CTRL_CE_STOP_ACTIVE;
-}
-
 static void aspeed_smc_flash_update_cs(AspeedSMCFlash *fl)
 {
     const AspeedSMCState *s = fl->controller;
-- 
2.7.4

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

* [Qemu-devel] [PULL 14/36] aspeed/smc: reset flash after each test
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (12 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 13/36] aspeed/smc: handle SPI flash Command mode Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 15/36] aspeed/smc: extend tests for Command mode Peter Maydell
                   ` (21 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

Let's make sure when each test is run that the flash object is in an
initial state and did not keep configuration from the previous tests.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-id: 1483979087-32663-9-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/m25p80-test.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/tests/m25p80-test.c b/tests/m25p80-test.c
index cb7ec81..8dd550d 100644
--- a/tests/m25p80-test.c
+++ b/tests/m25p80-test.c
@@ -50,6 +50,8 @@ enum {
     READ = 0x03,
     PP = 0x02,
     WREN = 0x6,
+    RESET_ENABLE = 0x66,
+    RESET_MEMORY = 0x99,
     EN_4BYTE_ADDR = 0xB7,
     ERASE_SECTOR = 0xd8,
 };
@@ -76,6 +78,14 @@ static void spi_conf(uint32_t value)
     writel(ASPEED_FMC_BASE + R_CONF, conf);
 }
 
+static void spi_conf_remove(uint32_t value)
+{
+    uint32_t conf = readl(ASPEED_FMC_BASE + R_CONF);
+
+    conf &= ~value;
+    writel(ASPEED_FMC_BASE + R_CONF, conf);
+}
+
 static void spi_ctrl_start_user(void)
 {
     uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
@@ -95,6 +105,18 @@ static void spi_ctrl_stop_user(void)
     writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
 }
 
+static void flash_reset(void)
+{
+    spi_conf(CONF_ENABLE_W0);
+
+    spi_ctrl_start_user();
+    writeb(ASPEED_FLASH_BASE, RESET_ENABLE);
+    writeb(ASPEED_FLASH_BASE, RESET_MEMORY);
+    spi_ctrl_stop_user();
+
+    spi_conf_remove(CONF_ENABLE_W0);
+}
+
 static void test_read_jedec(void)
 {
     uint32_t jedec = 0x0;
@@ -108,6 +130,8 @@ static void test_read_jedec(void)
     jedec |= readb(ASPEED_FLASH_BASE);
     spi_ctrl_stop_user();
 
+    flash_reset();
+
     g_assert_cmphex(jedec, ==, FLASH_JEDEC);
 }
 
@@ -155,6 +179,8 @@ static void test_erase_sector(void)
     for (i = 0; i < PAGE_SIZE / 4; i++) {
         g_assert_cmphex(page[i], ==, 0xffffffff);
     }
+
+    flash_reset();
 }
 
 static void test_erase_all(void)
@@ -182,6 +208,8 @@ static void test_erase_all(void)
     for (i = 0; i < PAGE_SIZE / 4; i++) {
         g_assert_cmphex(page[i], ==, 0xffffffff);
     }
+
+    flash_reset();
 }
 
 static void test_write_page(void)
@@ -195,6 +223,7 @@ static void test_write_page(void)
 
     spi_ctrl_start_user();
     writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
+    writeb(ASPEED_FLASH_BASE, WREN);
     writeb(ASPEED_FLASH_BASE, PP);
     writel(ASPEED_FLASH_BASE, make_be32(my_page_addr));
 
@@ -215,6 +244,8 @@ static void test_write_page(void)
     for (i = 0; i < PAGE_SIZE / 4; i++) {
         g_assert_cmphex(page[i], ==, 0xffffffff);
     }
+
+    flash_reset();
 }
 
 static char tmp_path[] = "/tmp/qtest.m25p80.XXXXXX";
-- 
2.7.4

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

* [Qemu-devel] [PULL 15/36] aspeed/smc: extend tests for Command mode
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (13 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 14/36] aspeed/smc: reset flash after each test Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 16/36] aspeed: use first FMC flash as a boot ROM Peter Maydell
                   ` (20 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

The Aspeed SMC controllers have a mode (Command mode) in which
accesses to the flash content are no different than doing MMIOs. The
controller generates all the necessary commands to load (or store)
data in memory.

So add a couple of tests doing direct reads and writes on the AHB bus.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1483979087-32663-10-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/m25p80-test.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/tests/m25p80-test.c b/tests/m25p80-test.c
index 8dd550d..244aa33 100644
--- a/tests/m25p80-test.c
+++ b/tests/m25p80-test.c
@@ -36,6 +36,9 @@
 #define   CRTL_EXTENDED0       0  /* 32 bit addressing for SPI */
 #define R_CTRL0             0x10
 #define   CTRL_CE_STOP_ACTIVE  (1 << 2)
+#define   CTRL_READMODE        0x0
+#define   CTRL_FREADMODE       0x1
+#define   CTRL_WRITEMODE       0x2
 #define   CTRL_USERMODE        0x3
 
 #define ASPEED_FMC_BASE    0x1E620000
@@ -86,6 +89,22 @@ static void spi_conf_remove(uint32_t value)
     writel(ASPEED_FMC_BASE + R_CONF, conf);
 }
 
+static void spi_ce_ctrl(uint32_t value)
+{
+    uint32_t conf = readl(ASPEED_FMC_BASE + R_CE_CTRL);
+
+    conf |= value;
+    writel(ASPEED_FMC_BASE + R_CE_CTRL, conf);
+}
+
+static void spi_ctrl_setmode(uint8_t mode, uint8_t cmd)
+{
+    uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
+    ctrl &= ~(CTRL_USERMODE | 0xff << 16);
+    ctrl |= mode | (cmd << 16);
+    writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
+}
+
 static void spi_ctrl_start_user(void)
 {
     uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
@@ -152,6 +171,18 @@ static void read_page(uint32_t addr, uint32_t *page)
     spi_ctrl_stop_user();
 }
 
+static void read_page_mem(uint32_t addr, uint32_t *page)
+{
+    int i;
+
+    /* move out USER mode to use direct reads from the AHB bus */
+    spi_ctrl_setmode(CTRL_READMODE, READ);
+
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        page[i] = make_be32(readl(ASPEED_FLASH_BASE + addr + i * 4));
+    }
+}
+
 static void test_erase_sector(void)
 {
     uint32_t some_page_addr = 0x600 * PAGE_SIZE;
@@ -248,6 +279,75 @@ static void test_write_page(void)
     flash_reset();
 }
 
+static void test_read_page_mem(void)
+{
+    uint32_t my_page_addr = 0x14000 * PAGE_SIZE; /* beyond 16MB */
+    uint32_t some_page_addr = 0x15000 * PAGE_SIZE;
+    uint32_t page[PAGE_SIZE / 4];
+    int i;
+
+    /* Enable 4BYTE mode for controller. This is should be strapped by
+     * HW for CE0 anyhow.
+     */
+    spi_ce_ctrl(1 << CRTL_EXTENDED0);
+
+    /* Enable 4BYTE mode for flash. */
+    spi_conf(CONF_ENABLE_W0);
+    spi_ctrl_start_user();
+    writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
+    spi_ctrl_stop_user();
+    spi_conf_remove(CONF_ENABLE_W0);
+
+    /* Check what was written */
+    read_page_mem(my_page_addr, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
+    }
+
+    /* Check some other page. It should be full of 0xff */
+    read_page_mem(some_page_addr, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, 0xffffffff);
+    }
+
+    flash_reset();
+}
+
+static void test_write_page_mem(void)
+{
+    uint32_t my_page_addr = 0x15000 * PAGE_SIZE;
+    uint32_t page[PAGE_SIZE / 4];
+    int i;
+
+    /* Enable 4BYTE mode for controller. This is should be strapped by
+     * HW for CE0 anyhow.
+     */
+    spi_ce_ctrl(1 << CRTL_EXTENDED0);
+
+    /* Enable 4BYTE mode for flash. */
+    spi_conf(CONF_ENABLE_W0);
+    spi_ctrl_start_user();
+    writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
+    writeb(ASPEED_FLASH_BASE, WREN);
+    spi_ctrl_stop_user();
+
+    /* move out USER mode to use direct writes to the AHB bus */
+    spi_ctrl_setmode(CTRL_WRITEMODE, PP);
+
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        writel(ASPEED_FLASH_BASE + my_page_addr + i * 4,
+               make_be32(my_page_addr + i * 4));
+    }
+
+    /* Check what was written */
+    read_page_mem(my_page_addr, page);
+    for (i = 0; i < PAGE_SIZE / 4; i++) {
+        g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
+    }
+
+    flash_reset();
+}
+
 static char tmp_path[] = "/tmp/qtest.m25p80.XXXXXX";
 
 int main(int argc, char **argv)
@@ -273,6 +373,8 @@ int main(int argc, char **argv)
     qtest_add_func("/m25p80/erase_sector", test_erase_sector);
     qtest_add_func("/m25p80/erase_all",  test_erase_all);
     qtest_add_func("/m25p80/write_page", test_write_page);
+    qtest_add_func("/m25p80/read_page_mem", test_read_page_mem);
+    qtest_add_func("/m25p80/write_page_mem", test_write_page_mem);
 
     ret = g_test_run();
 
-- 
2.7.4

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

* [Qemu-devel] [PULL 16/36] aspeed: use first FMC flash as a boot ROM
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (14 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 15/36] aspeed/smc: extend tests for Command mode Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 17/36] arm: virt: Fix segmentation fault when specifying an unsupported CPU Peter Maydell
                   ` (19 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Cédric Le Goater <clg@kaod.org>

Create a ROM region, using the default size of the mapping window for
the CE0 FMC flash module, and fill it with the flash content.

This is a little hacky but until we can boot from a MMIO region, it
seems difficult to do anything else.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Message-id: 1483979087-32663-11-git-send-email-clg@kaod.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/aspeed.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 40c1383..a92c2f1 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -20,6 +20,8 @@
 #include "qemu/log.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
+#include "hw/loader.h"
+#include "qemu/error-report.h"
 
 static struct arm_boot_info aspeed_board_binfo = {
     .board_id = -1, /* device-tree-only board */
@@ -104,6 +106,28 @@ static const AspeedBoardConfig aspeed_boards[] = {
     },
 };
 
+#define FIRMWARE_ADDR 0x0
+
+static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
+                           Error **errp)
+{
+    BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+    uint8_t *storage;
+
+    if (rom_size > blk_getlength(blk)) {
+        rom_size = blk_getlength(blk);
+    }
+
+    storage = g_new0(uint8_t, rom_size);
+    if (blk_pread(blk, 0, storage, rom_size) < 0) {
+        error_setg(errp, "failed to read the initial flash content");
+        return;
+    }
+
+    rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
+    g_free(storage);
+}
+
 static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
                                       Error **errp)
 {
@@ -135,6 +159,7 @@ static void aspeed_board_init(MachineState *machine,
 {
     AspeedBoardState *bmc;
     AspeedSoCClass *sc;
+    DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
 
     bmc = g_new0(AspeedBoardState, 1);
     object_initialize(&bmc->soc, (sizeof(bmc->soc)), cfg->soc_name);
@@ -168,6 +193,22 @@ static void aspeed_board_init(MachineState *machine,
     aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
     aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
 
+    /* Install first FMC flash content as a boot rom. */
+    if (drive0) {
+        AspeedSMCFlash *fl = &bmc->soc.fmc.flashes[0];
+        MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
+
+        /*
+         * create a ROM region using the default mapping window size of
+         * the flash module.
+         */
+        memory_region_init_rom(boot_rom, OBJECT(bmc), "aspeed.boot_rom",
+                               fl->size, &error_abort);
+        memory_region_add_subregion(get_system_memory(), FIRMWARE_ADDR,
+                                    boot_rom);
+        write_boot_rom(drive0, FIRMWARE_ADDR, fl->size, &error_abort);
+    }
+
     aspeed_board_binfo.kernel_filename = machine->kernel_filename;
     aspeed_board_binfo.initrd_filename = machine->initrd_filename;
     aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline;
-- 
2.7.4

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

* [Qemu-devel] [PULL 17/36] arm: virt: Fix segmentation fault when specifying an unsupported CPU
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (15 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 16/36] aspeed: use first FMC flash as a boot ROM Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 18/36] hw/arm/virt-acpi - reserve ECAM space as PNP0C02 device Peter Maydell
                   ` (18 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Shannon Zhao <shannon.zhao@linaro.org>

Using -cpu cortex-a9 (or any other unsupported CPU) with the virt
board will cause QEMU to segmentation fault.  This bug was introduced
in commit 9ac4ef77, which incorrectly added a NULL terminator when
converting the VirtBoardInfo array into a simple array of strings
defining the valid CPUs. The cpuname_valid() loop already has
a termination condition based on ARRAY_SIZE, so the NULL is
spurious and causes the strcmp() to segfault if we reach it.
Delete the NULL.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Message-id: 1484619334-10488-1-git-send-email-zhaoshenglong@huawei.com
[PMM: expanded commit message]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 7a03f84..95ac585 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -167,7 +167,6 @@ static const char *valid_cpus[] = {
     "cortex-a53",
     "cortex-a57",
     "host",
-    NULL
 };
 
 static bool cpuname_valid(const char *cpu)
-- 
2.7.4

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

* [Qemu-devel] [PULL 18/36] hw/arm/virt-acpi - reserve ECAM space as PNP0C02 device
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (16 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 17/36] arm: virt: Fix segmentation fault when specifying an unsupported CPU Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 19/36] hw/intc/arm_gicv3: Add external IRQ lines for VIRQ and VFIQ Peter Maydell
                   ` (17 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Linux for arm64 v4.10 and later will complain if the ECAM config space is
not reserved in the ACPI namespace:

  acpi PNP0A08:00: [Firmware Bug]: ECAM area [mem 0x3f000000-0x3fffffff] not reserved in ACPI namespace

The rationale is that OSes that don't consume the MCFG table should still
be able to infer that the PCI config space MMIO region is occupied.

So update the ACPI table generation routine to add this reservation.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Message-id: 1484328738-21149-1-git-send-email-ard.biesheuvel@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt-acpi-build.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 085a611..50d52f6 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -310,6 +310,13 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
     Aml *dev_rp0 = aml_device("%s", "RP0");
     aml_append(dev_rp0, aml_name_decl("_ADR", aml_int(0)));
     aml_append(dev, dev_rp0);
+
+    Aml *dev_res0 = aml_device("%s", "RES0");
+    aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02")));
+    crs = aml_resource_template();
+    aml_append(crs, aml_memory32_fixed(base_ecam, size_ecam, AML_READ_WRITE));
+    aml_append(dev_res0, aml_name_decl("_CRS", crs));
+    aml_append(dev, dev_res0);
     aml_append(scope, dev);
 }
 
-- 
2.7.4

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

* [Qemu-devel] [PULL 19/36] hw/intc/arm_gicv3: Add external IRQ lines for VIRQ and VFIQ
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (17 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 18/36] hw/arm/virt-acpi - reserve ECAM space as PNP0C02 device Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 20/36] hw/intc/arm_gic: " Peter Maydell
                   ` (16 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Augment the GICv3's QOM device interface by adding two
new sets of sysbus IRQ lines, to signal VIRQ and VFIQ to
each CPU.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
Message-id: 1483977924-14522-2-git-send-email-peter.maydell@linaro.org
---
 include/hw/intc/arm_gicv3_common.h | 2 ++
 hw/intc/arm_gicv3_common.c         | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
index 341a311..beb2c77 100644
--- a/include/hw/intc/arm_gicv3_common.h
+++ b/include/hw/intc/arm_gicv3_common.h
@@ -145,6 +145,8 @@ struct GICv3CPUState {
     CPUState *cpu;
     qemu_irq parent_irq;
     qemu_irq parent_fiq;
+    qemu_irq parent_virq;
+    qemu_irq parent_vfiq;
 
     /* Redistributor */
     uint32_t level;                  /* Current IRQ level */
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index 0aa9b9c..0ee67a4 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -126,6 +126,12 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
     for (i = 0; i < s->num_cpu; i++) {
         sysbus_init_irq(sbd, &s->cpu[i].parent_fiq);
     }
+    for (i = 0; i < s->num_cpu; i++) {
+        sysbus_init_irq(sbd, &s->cpu[i].parent_virq);
+    }
+    for (i = 0; i < s->num_cpu; i++) {
+        sysbus_init_irq(sbd, &s->cpu[i].parent_vfiq);
+    }
 
     memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s,
                           "gicv3_dist", 0x10000);
-- 
2.7.4

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

* [Qemu-devel] [PULL 20/36] hw/intc/arm_gic: Add external IRQ lines for VIRQ and VFIQ
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (18 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 19/36] hw/intc/arm_gicv3: Add external IRQ lines for VIRQ and VFIQ Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 21/36] target-arm: Expose output GPIO line for VCPU maintenance interrupt Peter Maydell
                   ` (15 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Augment the GIC's QOM device interface by adding two
new sets of sysbus IRQ lines, to signal VIRQ and VFIQ to
each CPU.

We never use these, but it's helpful to keep the v2-and-earlier
GIC's external interface in line with that of the GICv3 to
avoid board code having to add extra code conditional on which
version of the GIC is in use.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1483977924-14522-3-git-send-email-peter.maydell@linaro.org
---
 include/hw/intc/arm_gic_common.h | 2 ++
 hw/intc/arm_gic_common.c         | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h
index f4c349a..af3ca18 100644
--- a/include/hw/intc/arm_gic_common.h
+++ b/include/hw/intc/arm_gic_common.h
@@ -55,6 +55,8 @@ typedef struct GICState {
 
     qemu_irq parent_irq[GIC_NCPU];
     qemu_irq parent_fiq[GIC_NCPU];
+    qemu_irq parent_virq[GIC_NCPU];
+    qemu_irq parent_vfiq[GIC_NCPU];
     /* GICD_CTLR; for a GIC with the security extensions the NS banked version
      * of this register is just an alias of bit 1 of the S banked version.
      */
diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
index 0a1f56a..4a8df44 100644
--- a/hw/intc/arm_gic_common.c
+++ b/hw/intc/arm_gic_common.c
@@ -110,6 +110,12 @@ void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler,
     for (i = 0; i < s->num_cpu; i++) {
         sysbus_init_irq(sbd, &s->parent_fiq[i]);
     }
+    for (i = 0; i < s->num_cpu; i++) {
+        sysbus_init_irq(sbd, &s->parent_virq[i]);
+    }
+    for (i = 0; i < s->num_cpu; i++) {
+        sysbus_init_irq(sbd, &s->parent_vfiq[i]);
+    }
 
     /* Distributor */
     memory_region_init_io(&s->iomem, OBJECT(s), ops, s, "gic_dist", 0x1000);
-- 
2.7.4

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

* [Qemu-devel] [PULL 21/36] target-arm: Expose output GPIO line for VCPU maintenance interrupt
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (19 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 20/36] hw/intc/arm_gic: " Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 22/36] hw/arm/virt: Wire VIRQ, VFIQ, maintenance irq lines from GIC to CPU Peter Maydell
                   ` (14 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

The GICv3 support for virtualization includes an outbound
maintenance interrupt signal which is asserted when the
CPU interface wants to signal to the hypervisor that it
needs attention. Expose this as an outbound GPIO line from
the CPU object which can be wired up as a physical interrupt
line by the board code (as we do already for the CPU timers).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
Message-id: 1483977924-14522-4-git-send-email-peter.maydell@linaro.org
---
 target/arm/cpu.h | 2 ++
 target/arm/cpu.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 7bd16ee..fa09498 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -558,6 +558,8 @@ struct ARMCPU {
     QEMUTimer *gt_timer[NUM_GTIMERS];
     /* GPIO outputs for generic timer */
     qemu_irq gt_timer_outputs[NUM_GTIMERS];
+    /* GPIO output for GICv3 maintenance interrupt signal */
+    qemu_irq gicv3_maintenance_interrupt;
 
     /* MemoryRegion to use for secure physical accesses */
     MemoryRegion *secure_memory;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 9104611..93ebbc9 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -465,6 +465,9 @@ static void arm_cpu_initfn(Object *obj)
                                                 arm_gt_stimer_cb, cpu);
     qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs,
                        ARRAY_SIZE(cpu->gt_timer_outputs));
+
+    qdev_init_gpio_out_named(DEVICE(cpu), &cpu->gicv3_maintenance_interrupt,
+                             "gicv3-maintenance-interrupt", 1);
 #endif
 
     /* DTB consumers generally don't in fact care what the 'compatible'
-- 
2.7.4

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

* [Qemu-devel] [PULL 22/36] hw/arm/virt: Wire VIRQ, VFIQ, maintenance irq lines from GIC to CPU
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (20 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 21/36] target-arm: Expose output GPIO line for VCPU maintenance interrupt Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 23/36] target-arm: Add ARMCPU fields for GIC CPU i/f config Peter Maydell
                   ` (13 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Wire the new VIRQ, VFIQ and maintenance interrupt lines from the
GIC to each CPU.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1483977924-14522-5-git-send-email-peter.maydell@linaro.org
---
 include/hw/arm/virt.h |  2 ++
 hw/arm/virt.c         | 14 +++++++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index eb1c63d..b8a19ec 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -39,6 +39,8 @@
 #define NUM_GICV2M_SPIS       64
 #define NUM_VIRTIO_TRANSPORTS 32
 
+#define ARCH_GICV3_MAINT_IRQ  9
+
 #define ARCH_TIMER_VIRT_IRQ   11
 #define ARCH_TIMER_S_EL1_IRQ  13
 #define ARCH_TIMER_NS_EL1_IRQ 14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 95ac585..d931d17 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -546,9 +546,9 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
         sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base);
     }
 
-    /* Wire the outputs from each CPU's generic timer to the
-     * appropriate GIC PPI inputs, and the GIC's IRQ output to
-     * the CPU's IRQ input.
+    /* Wire the outputs from each CPU's generic timer and the GICv3
+     * maintenance interrupt signal to the appropriate GIC PPI inputs,
+     * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
      */
     for (i = 0; i < smp_cpus; i++) {
         DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
@@ -570,9 +570,17 @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
                                                    ppibase + timer_irq[irq]));
         }
 
+        qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
+                                    qdev_get_gpio_in(gicdev, ppibase
+                                                     + ARCH_GICV3_MAINT_IRQ));
+
         sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
         sysbus_connect_irq(gicbusdev, i + smp_cpus,
                            qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+        sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
+        sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
     }
 
     for (i = 0; i < NUM_IRQS; i++) {
-- 
2.7.4

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

* [Qemu-devel] [PULL 23/36] target-arm: Add ARMCPU fields for GIC CPU i/f config
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (21 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 22/36] hw/arm/virt: Wire VIRQ, VFIQ, maintenance irq lines from GIC to CPU Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 24/36] hw/intc/gicv3: Add defines for ICH system register fields Peter Maydell
                   ` (12 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Add fields to the ARMCPU structure to allow CPU classes to
specify the configurable aspects of their GIC CPU interface.
In particular, the virtualization support allows different
values for number of list registers, priority bits and
preemption bits.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
Message-id: 1483977924-14522-6-git-send-email-peter.maydell@linaro.org
---
 target/arm/cpu.h   | 5 +++++
 target/arm/cpu64.c | 6 ++++++
 2 files changed, 11 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index fa09498..16c7c10 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -662,6 +662,11 @@ struct ARMCPU {
     uint32_t dcz_blocksize;
     uint64_t rvbar;
 
+    /* Configurable aspects of GIC cpu interface (which is part of the CPU) */
+    int gic_num_lrs; /* number of list registers */
+    int gic_vpribits; /* number of virtual priority bits */
+    int gic_vprebits; /* number of virtual preemption bits */
+
     ARMELChangeHook *el_change_hook;
     void *el_change_hook_opaque;
 };
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 549cb1e..73c7f31 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -147,6 +147,9 @@ static void aarch64_a57_initfn(Object *obj)
     cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
     cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
     cpu->dcz_blocksize = 4; /* 64 bytes */
+    cpu->gic_num_lrs = 4;
+    cpu->gic_vpribits = 5;
+    cpu->gic_vprebits = 5;
     define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
 }
 
@@ -201,6 +204,9 @@ static void aarch64_a53_initfn(Object *obj)
     cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
     cpu->ccsidr[2] = 0x707fe07a; /* 1024KB L2 cache */
     cpu->dcz_blocksize = 4; /* 64 bytes */
+    cpu->gic_num_lrs = 4;
+    cpu->gic_vpribits = 5;
+    cpu->gic_vprebits = 5;
     define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
 }
 
-- 
2.7.4

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

* [Qemu-devel] [PULL 24/36] hw/intc/gicv3: Add defines for ICH system register fields
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (22 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 23/36] target-arm: Add ARMCPU fields for GIC CPU i/f config Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 25/36] hw/intc/gicv3: Add data fields for virtualization support Peter Maydell
                   ` (11 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Add defines to gicv3_internal.h for fields in the ICH_*
system registers which form the GIC virtualization control
interface.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1483977924-14522-7-git-send-email-peter.maydell@linaro.org
---
 hw/intc/gicv3_internal.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
index 8f3567e..aeb801d 100644
--- a/hw/intc/gicv3_internal.h
+++ b/hw/intc/gicv3_internal.h
@@ -159,6 +159,85 @@
 #define ICC_CTLR_EL3_A3V (1U << 15)
 #define ICC_CTLR_EL3_NDS (1U << 17)
 
+#define ICH_VMCR_EL2_VENG0_SHIFT 0
+#define ICH_VMCR_EL2_VENG0 (1U << ICH_VMCR_EL2_VENG0_SHIFT)
+#define ICH_VMCR_EL2_VENG1_SHIFT 1
+#define ICH_VMCR_EL2_VENG1 (1U << ICH_VMCR_EL2_VENG1_SHIFT)
+#define ICH_VMCR_EL2_VACKCTL (1U << 2)
+#define ICH_VMCR_EL2_VFIQEN (1U << 3)
+#define ICH_VMCR_EL2_VCBPR_SHIFT 4
+#define ICH_VMCR_EL2_VCBPR (1U << ICH_VMCR_EL2_VCBPR_SHIFT)
+#define ICH_VMCR_EL2_VEOIM_SHIFT 9
+#define ICH_VMCR_EL2_VEOIM (1U << ICH_VMCR_EL2_VEOIM_SHIFT)
+#define ICH_VMCR_EL2_VBPR1_SHIFT 18
+#define ICH_VMCR_EL2_VBPR1_LENGTH 3
+#define ICH_VMCR_EL2_VBPR1_MASK (0x7U << ICH_VMCR_EL2_VBPR1_SHIFT)
+#define ICH_VMCR_EL2_VBPR0_SHIFT 21
+#define ICH_VMCR_EL2_VBPR0_LENGTH 3
+#define ICH_VMCR_EL2_VBPR0_MASK (0x7U << ICH_VMCR_EL2_VBPR0_SHIFT)
+#define ICH_VMCR_EL2_VPMR_SHIFT 24
+#define ICH_VMCR_EL2_VPMR_LENGTH 8
+#define ICH_VMCR_EL2_VPMR_MASK (0xffU << ICH_VMCR_EL2_VPMR_SHIFT)
+
+#define ICH_HCR_EL2_EN (1U << 0)
+#define ICH_HCR_EL2_UIE (1U << 1)
+#define ICH_HCR_EL2_LRENPIE (1U << 2)
+#define ICH_HCR_EL2_NPIE (1U << 3)
+#define ICH_HCR_EL2_VGRP0EIE (1U << 4)
+#define ICH_HCR_EL2_VGRP0DIE (1U << 5)
+#define ICH_HCR_EL2_VGRP1EIE (1U << 6)
+#define ICH_HCR_EL2_VGRP1DIE (1U << 7)
+#define ICH_HCR_EL2_TC (1U << 10)
+#define ICH_HCR_EL2_TALL0 (1U << 11)
+#define ICH_HCR_EL2_TALL1 (1U << 12)
+#define ICH_HCR_EL2_TSEI (1U << 13)
+#define ICH_HCR_EL2_TDIR (1U << 14)
+#define ICH_HCR_EL2_EOICOUNT_SHIFT 27
+#define ICH_HCR_EL2_EOICOUNT_LENGTH 5
+#define ICH_HCR_EL2_EOICOUNT_MASK (0x1fU << ICH_HCR_EL2_EOICOUNT_SHIFT)
+
+#define ICH_LR_EL2_VINTID_SHIFT 0
+#define ICH_LR_EL2_VINTID_LENGTH 32
+#define ICH_LR_EL2_VINTID_MASK (0xffffffffULL << ICH_LR_EL2_VINTID_SHIFT)
+#define ICH_LR_EL2_PINTID_SHIFT 32
+#define ICH_LR_EL2_PINTID_LENGTH 10
+#define ICH_LR_EL2_PINTID_MASK (0x3ffULL << ICH_LR_EL2_PINTID_SHIFT)
+/* Note that EOI shares with the top bit of the pINTID field */
+#define ICH_LR_EL2_EOI (1ULL << 41)
+#define ICH_LR_EL2_PRIORITY_SHIFT 48
+#define ICH_LR_EL2_PRIORITY_LENGTH 8
+#define ICH_LR_EL2_PRIORITY_MASK (0xffULL << ICH_LR_EL2_PRIORITY_SHIFT)
+#define ICH_LR_EL2_GROUP (1ULL << 60)
+#define ICH_LR_EL2_HW (1ULL << 61)
+#define ICH_LR_EL2_STATE_SHIFT 62
+#define ICH_LR_EL2_STATE_LENGTH 2
+#define ICH_LR_EL2_STATE_MASK (3ULL << ICH_LR_EL2_STATE_SHIFT)
+/* values for the state field: */
+#define ICH_LR_EL2_STATE_INVALID 0
+#define ICH_LR_EL2_STATE_PENDING 1
+#define ICH_LR_EL2_STATE_ACTIVE 2
+#define ICH_LR_EL2_STATE_ACTIVE_PENDING 3
+#define ICH_LR_EL2_STATE_PENDING_BIT (1ULL << ICH_LR_EL2_STATE_SHIFT)
+#define ICH_LR_EL2_STATE_ACTIVE_BIT (2ULL << ICH_LR_EL2_STATE_SHIFT)
+
+#define ICH_MISR_EL2_EOI (1U << 0)
+#define ICH_MISR_EL2_U (1U << 1)
+#define ICH_MISR_EL2_LRENP (1U << 2)
+#define ICH_MISR_EL2_NP (1U << 3)
+#define ICH_MISR_EL2_VGRP0E (1U << 4)
+#define ICH_MISR_EL2_VGRP0D (1U << 5)
+#define ICH_MISR_EL2_VGRP1E (1U << 6)
+#define ICH_MISR_EL2_VGRP1D (1U << 7)
+
+#define ICH_VTR_EL2_LISTREGS_SHIFT 0
+#define ICH_VTR_EL2_TDS (1U << 19)
+#define ICH_VTR_EL2_NV4 (1U << 20)
+#define ICH_VTR_EL2_A3V (1U << 21)
+#define ICH_VTR_EL2_SEIS (1U << 22)
+#define ICH_VTR_EL2_IDBITS_SHIFT 23
+#define ICH_VTR_EL2_PREBITS_SHIFT 26
+#define ICH_VTR_EL2_PRIBITS_SHIFT 29
+
 /* Special interrupt IDs */
 #define INTID_SECURE 1020
 #define INTID_NONSECURE 1021
-- 
2.7.4

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

* [Qemu-devel] [PULL 25/36] hw/intc/gicv3: Add data fields for virtualization support
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (23 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 24/36] hw/intc/gicv3: Add defines for ICH system register fields Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 26/36] hw/intc/arm_gicv3: Add accessors for ICH_ system registers Peter Maydell
                   ` (10 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

As the first step in adding support for the virtualization
extensions to the GICv3 emulation:
 * add the necessary data fields to the state structures
 * add the fields to the migration state, as a subsection
   which is only present if virtualization is enabled

The use of a subsection means we retain migration
compatibility as EL2 is not enabled on any CPUs currently.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
Message-id: 1483977924-14522-8-git-send-email-peter.maydell@linaro.org
---
 include/hw/intc/arm_gicv3_common.h | 18 ++++++++++++++++++
 hw/intc/arm_gicv3_common.c         | 25 +++++++++++++++++++++++++
 hw/intc/arm_gicv3_cpuif.c          | 13 +++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
index beb2c77..665d3f8 100644
--- a/include/hw/intc/arm_gicv3_common.h
+++ b/include/hw/intc/arm_gicv3_common.h
@@ -38,6 +38,9 @@
 /* Number of SGI target-list bits */
 #define GICV3_TARGETLIST_BITS 16
 
+/* Maximum number of list registers (architectural limit) */
+#define GICV3_LR_MAX 16
+
 /* Minimum BPR for Secure, or when security not enabled */
 #define GIC_MIN_BPR 0
 /* Minimum BPR for Nonsecure when security is enabled */
@@ -175,6 +178,21 @@ struct GICv3CPUState {
     uint64_t icc_igrpen[3];
     uint64_t icc_ctlr_el3;
 
+    /* Virtualization control interface */
+    uint64_t ich_apr[3][4]; /* ich_apr[GICV3_G1][x] never used */
+    uint64_t ich_hcr_el2;
+    uint64_t ich_lr_el2[GICV3_LR_MAX];
+    uint64_t ich_vmcr_el2;
+
+    /* Properties of the CPU interface. These are initialized from
+     * the settings in the CPU proper.
+     * If the number of implemented list registers is 0 then the
+     * virtualization support is not implemented.
+     */
+    int num_list_regs;
+    int vpribits; /* number of virtual priority bits */
+    int vprebits; /* number of virtual preemption bits */
+
     /* Current highest priority pending interrupt for this CPU.
      * This is cached information that can be recalculated from the
      * real state above; it doesn't need to be migrated.
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index 0ee67a4..16b9b0f 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -49,6 +49,27 @@ static int gicv3_post_load(void *opaque, int version_id)
     return 0;
 }
 
+static bool virt_state_needed(void *opaque)
+{
+    GICv3CPUState *cs = opaque;
+
+    return cs->num_list_regs != 0;
+}
+
+static const VMStateDescription vmstate_gicv3_cpu_virt = {
+    .name = "arm_gicv3_cpu/virt",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = virt_state_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64_2DARRAY(ich_apr, GICv3CPUState, 3, 4),
+        VMSTATE_UINT64(ich_hcr_el2, GICv3CPUState),
+        VMSTATE_UINT64_ARRAY(ich_lr_el2, GICv3CPUState, GICV3_LR_MAX),
+        VMSTATE_UINT64(ich_vmcr_el2, GICv3CPUState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_gicv3_cpu = {
     .name = "arm_gicv3_cpu",
     .version_id = 1,
@@ -75,6 +96,10 @@ static const VMStateDescription vmstate_gicv3_cpu = {
         VMSTATE_UINT64_ARRAY(icc_igrpen, GICv3CPUState, 3),
         VMSTATE_UINT64(icc_ctlr_el3, GICv3CPUState),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (const VMStateDescription * []) {
+        &vmstate_gicv3_cpu_virt,
+        NULL
     }
 };
 
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index 35e8eb3..d2f859c 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -36,6 +36,12 @@ static bool gicv3_use_ns_bank(CPUARMState *env)
     return !arm_is_secure_below_el3(env);
 }
 
+/* The minimum BPR for the virtual interface is a configurable property */
+static inline int icv_min_vbpr(GICv3CPUState *cs)
+{
+    return 7 - cs->vprebits;
+}
+
 static int icc_highest_active_prio(GICv3CPUState *cs)
 {
     /* Calculate the current running priority based on the set bits
@@ -1081,6 +1087,13 @@ static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
     cs->icc_ctlr_el3 = ICC_CTLR_EL3_NDS | ICC_CTLR_EL3_A3V |
         (1 << ICC_CTLR_EL3_IDBITS_SHIFT) |
         (7 << ICC_CTLR_EL3_PRIBITS_SHIFT);
+
+    memset(cs->ich_apr, 0, sizeof(cs->ich_apr));
+    cs->ich_hcr_el2 = 0;
+    memset(cs->ich_lr_el2, 0, sizeof(cs->ich_lr_el2));
+    cs->ich_vmcr_el2 = ICH_VMCR_EL2_VFIQEN |
+        (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR1_SHIFT) |
+        (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR0_SHIFT);
 }
 
 static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
-- 
2.7.4

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

* [Qemu-devel] [PULL 26/36] hw/intc/arm_gicv3: Add accessors for ICH_ system registers
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (24 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 25/36] hw/intc/gicv3: Add data fields for virtualization support Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-26  9:35   ` Paolo Bonzini
  2017-01-19 14:09 ` [Qemu-devel] [PULL 27/36] hw/intc/arm_gicv3: Implement ICV_ registers which are just accessors Peter Maydell
                   ` (9 subsequent siblings)
  35 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

The GICv3 virtualization interface includes system registers
accessible only to the hypervisor which form the control
interface for interrupt virtualization. Implement these
registers.

The function gicv3_cpuif_virt_update() which determines
whether it needs to signal vIRQ, vFIQ or a maintenance
interrupt is introduced here as a stub function -- its
implementation will be added in a subsequent commit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1483977924-14522-9-git-send-email-peter.maydell@linaro.org
---
 hw/intc/arm_gicv3_cpuif.c | 477 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/intc/trace-events      |  16 ++
 2 files changed, 493 insertions(+)

diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index d2f859c..585c91c 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -42,6 +42,132 @@ static inline int icv_min_vbpr(GICv3CPUState *cs)
     return 7 - cs->vprebits;
 }
 
+/* Simple accessor functions for LR fields */
+static int ich_lr_state(uint64_t lr)
+{
+    return extract64(lr, ICH_LR_EL2_STATE_SHIFT, ICH_LR_EL2_STATE_LENGTH);
+}
+
+static int read_vbpr(GICv3CPUState *cs, int grp)
+{
+    /* Read VBPR value out of the VMCR field (caller must handle
+     * VCBPR effects if required)
+     */
+    if (grp == GICV3_G0) {
+        return extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VBPR0_SHIFT,
+                     ICH_VMCR_EL2_VBPR0_LENGTH);
+    } else {
+        return extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VBPR1_SHIFT,
+                         ICH_VMCR_EL2_VBPR1_LENGTH);
+    }
+}
+
+static void write_vbpr(GICv3CPUState *cs, int grp, int value)
+{
+    /* Write new VBPR1 value, handling the "writing a value less than
+     * the minimum sets it to the minimum" semantics.
+     */
+    int min = icv_min_vbpr(cs);
+
+    if (grp != GICV3_G0) {
+        min++;
+    }
+
+    value = MAX(value, min);
+
+    if (grp == GICV3_G0) {
+        cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VBPR0_SHIFT,
+                                     ICH_VMCR_EL2_VBPR0_LENGTH, value);
+    } else {
+        cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VBPR1_SHIFT,
+                                     ICH_VMCR_EL2_VBPR1_LENGTH, value);
+    }
+}
+
+static uint32_t eoi_maintenance_interrupt_state(GICv3CPUState *cs,
+                                                uint32_t *misr)
+{
+    /* Return a set of bits indicating the EOI maintenance interrupt status
+     * for each list register. The EOI maintenance interrupt status is
+     * 1 if LR.State == 0 && LR.HW == 0 && LR.EOI == 1
+     * (see the GICv3 spec for the ICH_EISR_EL2 register).
+     * If misr is not NULL then we should also collect the information
+     * about the MISR.EOI, MISR.NP and MISR.U bits.
+     */
+    uint32_t value = 0;
+    int validcount = 0;
+    bool seenpending = false;
+    int i;
+
+    for (i = 0; i < cs->num_list_regs; i++) {
+        uint64_t lr = cs->ich_lr_el2[i];
+
+        if ((lr & (ICH_LR_EL2_STATE_MASK | ICH_LR_EL2_HW | ICH_LR_EL2_EOI))
+            == ICH_LR_EL2_EOI) {
+            value |= (1 << i);
+        }
+        if ((lr & ICH_LR_EL2_STATE_MASK)) {
+            validcount++;
+        }
+        if (ich_lr_state(lr) == ICH_LR_EL2_STATE_PENDING) {
+            seenpending = true;
+        }
+    }
+
+    if (misr) {
+        if (validcount < 2 && (cs->ich_hcr_el2 & ICH_HCR_EL2_UIE)) {
+            *misr |= ICH_MISR_EL2_U;
+        }
+        if (!seenpending && (cs->ich_hcr_el2 & ICH_HCR_EL2_NPIE)) {
+            *misr |= ICH_MISR_EL2_NP;
+        }
+        if (value) {
+            *misr |= ICH_MISR_EL2_EOI;
+        }
+    }
+    return value;
+}
+
+static uint32_t maintenance_interrupt_state(GICv3CPUState *cs)
+{
+    /* Return a set of bits indicating the maintenance interrupt status
+     * (as seen in the ICH_MISR_EL2 register).
+     */
+    uint32_t value = 0;
+
+    /* Scan list registers and fill in the U, NP and EOI bits */
+    eoi_maintenance_interrupt_state(cs, &value);
+
+    if (cs->ich_hcr_el2 & (ICH_HCR_EL2_LRENPIE | ICH_HCR_EL2_EOICOUNT_MASK)) {
+        value |= ICH_MISR_EL2_LRENP;
+    }
+
+    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_VGRP0EIE) &&
+        (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
+        value |= ICH_MISR_EL2_VGRP0E;
+    }
+
+    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) &&
+        !(cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
+        value |= ICH_MISR_EL2_VGRP0D;
+    }
+    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) &&
+        (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
+        value |= ICH_MISR_EL2_VGRP1E;
+    }
+
+    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_VGRP1DIE) &&
+        !(cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
+        value |= ICH_MISR_EL2_VGRP1D;
+    }
+
+    return value;
+}
+
+static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
+{
+}
+
 static int icc_highest_active_prio(GICv3CPUState *cs)
 {
     /* Calculate the current running priority based on the set bits
@@ -1334,6 +1460,306 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
     REGINFO_SENTINEL
 };
 
+static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int regno = ri->opc2 & 3;
+    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
+    uint64_t value;
+
+    value = cs->ich_apr[grp][regno];
+    trace_gicv3_ich_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int regno = ri->opc2 & 3;
+    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
+
+    trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
+
+    cs->ich_apr[grp][regno] = value & 0xFFFFFFFFU;
+    gicv3_cpuif_virt_update(cs);
+}
+
+static uint64_t ich_hcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value = cs->ich_hcr_el2;
+
+    trace_gicv3_ich_hcr_read(gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static void ich_hcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+
+    trace_gicv3_ich_hcr_write(gicv3_redist_affid(cs), value);
+
+    value &= ICH_HCR_EL2_EN | ICH_HCR_EL2_UIE | ICH_HCR_EL2_LRENPIE |
+        ICH_HCR_EL2_NPIE | ICH_HCR_EL2_VGRP0EIE | ICH_HCR_EL2_VGRP0DIE |
+        ICH_HCR_EL2_VGRP1EIE | ICH_HCR_EL2_VGRP1DIE | ICH_HCR_EL2_TC |
+        ICH_HCR_EL2_TALL0 | ICH_HCR_EL2_TALL1 | ICH_HCR_EL2_TSEI |
+        ICH_HCR_EL2_TDIR | ICH_HCR_EL2_EOICOUNT_MASK;
+
+    cs->ich_hcr_el2 = value;
+    gicv3_cpuif_virt_update(cs);
+}
+
+static uint64_t ich_vmcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value = cs->ich_vmcr_el2;
+
+    trace_gicv3_ich_vmcr_read(gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static void ich_vmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+
+    trace_gicv3_ich_vmcr_write(gicv3_redist_affid(cs), value);
+
+    value &= ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1 | ICH_VMCR_EL2_VCBPR |
+        ICH_VMCR_EL2_VEOIM | ICH_VMCR_EL2_VBPR1_MASK |
+        ICH_VMCR_EL2_VBPR0_MASK | ICH_VMCR_EL2_VPMR_MASK;
+    value |= ICH_VMCR_EL2_VFIQEN;
+
+    cs->ich_vmcr_el2 = value;
+    /* Enforce "writing BPRs to less than minimum sets them to the minimum"
+     * by reading and writing back the fields.
+     */
+    write_vbpr(cs, GICV3_G1, read_vbpr(cs, GICV3_G0));
+    write_vbpr(cs, GICV3_G1, read_vbpr(cs, GICV3_G1));
+
+    gicv3_cpuif_virt_update(cs);
+}
+
+static uint64_t ich_lr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int regno = ri->opc2 | ((ri->crm & 1) << 3);
+    uint64_t value;
+
+    /* This read function handles all of:
+     * 64-bit reads of the whole LR
+     * 32-bit reads of the low half of the LR
+     * 32-bit reads of the high half of the LR
+     */
+    if (ri->state == ARM_CP_STATE_AA32) {
+        if (ri->crm >= 14) {
+            value = extract64(cs->ich_lr_el2[regno], 32, 32);
+            trace_gicv3_ich_lrc_read(regno, gicv3_redist_affid(cs), value);
+        } else {
+            value = extract64(cs->ich_lr_el2[regno], 0, 32);
+            trace_gicv3_ich_lr32_read(regno, gicv3_redist_affid(cs), value);
+        }
+    } else {
+        value = cs->ich_lr_el2[regno];
+        trace_gicv3_ich_lr_read(regno, gicv3_redist_affid(cs), value);
+    }
+
+    return value;
+}
+
+static void ich_lr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int regno = ri->opc2 | ((ri->crm & 1) << 3);
+
+    /* This write function handles all of:
+     * 64-bit writes to the whole LR
+     * 32-bit writes to the low half of the LR
+     * 32-bit writes to the high half of the LR
+     */
+    if (ri->state == ARM_CP_STATE_AA32) {
+        if (ri->crm >= 14) {
+            trace_gicv3_ich_lrc_write(regno, gicv3_redist_affid(cs), value);
+            value = deposit64(cs->ich_lr_el2[regno], 32, 32, value);
+        } else {
+            trace_gicv3_ich_lr32_write(regno, gicv3_redist_affid(cs), value);
+            value = deposit64(cs->ich_lr_el2[regno], 0, 32, value);
+        }
+    } else {
+        trace_gicv3_ich_lr_write(regno, gicv3_redist_affid(cs), value);
+    }
+
+    /* Enforce RES0 bits in priority field */
+    if (cs->vpribits < 8) {
+        value = deposit64(value, ICH_LR_EL2_PRIORITY_SHIFT,
+                          8 - cs->vpribits, 0);
+    }
+
+    cs->ich_lr_el2[regno] = value;
+    gicv3_cpuif_virt_update(cs);
+}
+
+static uint64_t ich_vtr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value;
+
+    value = ((cs->num_list_regs - 1) << ICH_VTR_EL2_LISTREGS_SHIFT)
+        | ICH_VTR_EL2_TDS | ICH_VTR_EL2_NV4 | ICH_VTR_EL2_A3V
+        | (1 << ICH_VTR_EL2_IDBITS_SHIFT)
+        | ((cs->vprebits - 1) << ICH_VTR_EL2_PREBITS_SHIFT)
+        | ((cs->vpribits - 1) << ICH_VTR_EL2_PRIBITS_SHIFT);
+
+    trace_gicv3_ich_vtr_read(gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static uint64_t ich_misr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value = maintenance_interrupt_state(cs);
+
+    trace_gicv3_ich_misr_read(gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static uint64_t ich_eisr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value = eoi_maintenance_interrupt_state(cs, NULL);
+
+    trace_gicv3_ich_eisr_read(gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static uint64_t ich_elrsr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value = 0;
+    int i;
+
+    for (i = 0; i < cs->num_list_regs; i++) {
+        uint64_t lr = cs->ich_lr_el2[i];
+
+        if ((lr & ICH_LR_EL2_STATE_MASK) == 0 &&
+            ((lr & ICH_LR_EL2_HW) == 1 || (lr & ICH_LR_EL2_EOI) == 0)) {
+            value |= (1 << i);
+        }
+    }
+
+    trace_gicv3_ich_elrsr_read(gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
+    { .name = "ICH_AP0R0_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 0,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_ap_read,
+      .writefn = ich_ap_write,
+    },
+    { .name = "ICH_AP1R0_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 0,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_ap_read,
+      .writefn = ich_ap_write,
+    },
+    { .name = "ICH_HCR_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 0,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_hcr_read,
+      .writefn = ich_hcr_write,
+    },
+    { .name = "ICH_VTR_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 1,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_R,
+      .readfn = ich_vtr_read,
+    },
+    { .name = "ICH_MISR_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 2,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_R,
+      .readfn = ich_misr_read,
+    },
+    { .name = "ICH_EISR_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 3,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_R,
+      .readfn = ich_eisr_read,
+    },
+    { .name = "ICH_ELRSR_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 5,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_R,
+      .readfn = ich_elrsr_read,
+    },
+    { .name = "ICH_VMCR_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 11, .opc2 = 7,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_vmcr_read,
+      .writefn = ich_vmcr_write,
+    },
+    REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
+    { .name = "ICH_AP0R1_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 1,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_ap_read,
+      .writefn = ich_ap_write,
+    },
+    { .name = "ICH_AP1R1_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 1,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_ap_read,
+      .writefn = ich_ap_write,
+    },
+    REGINFO_SENTINEL
+};
+
+static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
+    { .name = "ICH_AP0R2_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 2,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_ap_read,
+      .writefn = ich_ap_write,
+    },
+    { .name = "ICH_AP0R3_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 8, .opc2 = 3,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_ap_read,
+      .writefn = ich_ap_write,
+    },
+    { .name = "ICH_AP1R2_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 2,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_ap_read,
+      .writefn = ich_ap_write,
+    },
+    { .name = "ICH_AP1R3_EL2", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 9, .opc2 = 3,
+      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+      .access = PL2_RW,
+      .readfn = ich_ap_read,
+      .writefn = ich_ap_write,
+    },
+    REGINFO_SENTINEL
+};
+
 static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)
 {
     GICv3CPUState *cs = opaque;
@@ -1362,6 +1788,57 @@ void gicv3_init_cpuif(GICv3State *s)
          * to need to register anyway.
          */
         define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
+        if (arm_feature(&cpu->env, ARM_FEATURE_EL2)
+            && cpu->gic_num_lrs) {
+            int j;
+
+            cs->num_list_regs = cpu->gic_num_lrs;
+            cs->vpribits = cpu->gic_vpribits;
+            cs->vprebits = cpu->gic_vprebits;
+
+            /* Check against architectural constraints: getting these
+             * wrong would be a bug in the CPU code defining these,
+             * and the implementation relies on them holding.
+             */
+            g_assert(cs->vprebits <= cs->vpribits);
+            g_assert(cs->vprebits >= 5 && cs->vprebits <= 7);
+            g_assert(cs->vpribits >= 5 && cs->vpribits <= 8);
+
+            define_arm_cp_regs(cpu, gicv3_cpuif_hcr_reginfo);
+
+            for (j = 0; j < cs->num_list_regs; j++) {
+                /* Note that the AArch64 LRs are 64-bit; the AArch32 LRs
+                 * are split into two cp15 regs, LR (the low part, with the
+                 * same encoding as the AArch64 LR) and LRC (the high part).
+                 */
+                ARMCPRegInfo lr_regset[] = {
+                    { .name = "ICH_LRn_EL2", .state = ARM_CP_STATE_BOTH,
+                      .opc0 = 3, .opc1 = 4, .crn = 12,
+                      .crm = 12 + (j >> 3), .opc2 = j & 7,
+                      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+                      .access = PL2_RW,
+                      .readfn = ich_lr_read,
+                      .writefn = ich_lr_write,
+                    },
+                    { .name = "ICH_LRCn_EL2", .state = ARM_CP_STATE_AA32,
+                      .cp = 15, .opc1 = 4, .crn = 12,
+                      .crm = 14 + (j >> 3), .opc2 = j & 7,
+                      .type = ARM_CP_IO | ARM_CP_NO_RAW,
+                      .access = PL2_RW,
+                      .readfn = ich_lr_read,
+                      .writefn = ich_lr_write,
+                    },
+                    REGINFO_SENTINEL
+                };
+                define_arm_cp_regs(cpu, lr_regset);
+            }
+            if (cs->vprebits >= 6) {
+                define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr1_reginfo);
+            }
+            if (cs->vprebits == 7) {
+                define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
+            }
+        }
         arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
     }
 }
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 340f617..4ac1ea2 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -107,6 +107,22 @@ gicv3_icc_hppir0_read(uint32_t cpu, uint64_t val) "GICv3 ICC_HPPIR0 read cpu %x
 gicv3_icc_hppir1_read(uint32_t cpu, uint64_t val) "GICv3 ICC_HPPIR1 read cpu %x value 0x%" PRIx64
 gicv3_icc_dir_write(uint32_t cpu, uint64_t val) "GICv3 ICC_DIR write cpu %x value 0x%" PRIx64
 gicv3_icc_rpr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_RPR read cpu %x value 0x%" PRIx64
+gicv3_ich_ap_read(int grp, int regno, uint32_t cpu, uint64_t val) "GICv3 ICH_AP%dR%d read cpu %x value 0x%" PRIx64
+gicv3_ich_ap_write(int grp, int regno, uint32_t cpu, uint64_t val) "GICv3 ICH_AP%dR%d write cpu %x value 0x%" PRIx64
+gicv3_ich_hcr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_HCR_EL2 read cpu %x value 0x%" PRIx64
+gicv3_ich_hcr_write(uint32_t cpu, uint64_t val) "GICv3 ICH_HCR_EL2 write cpu %x value 0x%" PRIx64
+gicv3_ich_vmcr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_VMCR_EL2 read cpu %x value 0x%" PRIx64
+gicv3_ich_vmcr_write(uint32_t cpu, uint64_t val) "GICv3 ICH_VMCR_EL2 write cpu %x value 0x%" PRIx64
+gicv3_ich_lr_read(int regno, uint32_t cpu, uint64_t val) "GICv3 ICH_LR%d_EL2 read cpu %x value 0x%" PRIx64
+gicv3_ich_lr32_read(int regno, uint32_t cpu, uint32_t val) "GICv3 ICH_LR%d read cpu %x value 0x%" PRIx32
+gicv3_ich_lrc_read(int regno, uint32_t cpu, uint32_t val) "GICv3 ICH_LRC%d read cpu %x value 0x%" PRIx32
+gicv3_ich_lr_write(int regno, uint32_t cpu, uint64_t val) "GICv3 ICH_LR%d_EL2 write cpu %x value 0x%" PRIx64
+gicv3_ich_lr32_write(int regno, uint32_t cpu, uint32_t val) "GICv3 ICH_LR%d write cpu %x value 0x%" PRIx32
+gicv3_ich_lrc_write(int regno, uint32_t cpu, uint32_t val) "GICv3 ICH_LRC%d write cpu %x value 0x%" PRIx32
+gicv3_ich_vtr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_VTR read cpu %x value 0x%" PRIx64
+gicv3_ich_misr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_MISR read cpu %x value 0x%" PRIx64
+gicv3_ich_eisr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_EISR read cpu %x value 0x%" PRIx64
+gicv3_ich_elrsr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_ELRSR read cpu %x value 0x%" PRIx64
 
 # hw/intc/arm_gicv3_dist.c
 gicv3_dist_read(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-- 
2.7.4

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

* [Qemu-devel] [PULL 27/36] hw/intc/arm_gicv3: Implement ICV_ registers which are just accessors
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (25 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 26/36] hw/intc/arm_gicv3: Add accessors for ICH_ system registers Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 28/36] hw/intc/arm_gicv3: Implement ICV_ HPPIR, DIR and RPR registers Peter Maydell
                   ` (8 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

If the HCR_EL2.IMO or FMO bits are set, accesses to ICC_
system registers are redirected to be accesses to ICV_
registers (the guest-visible interface to the virtual
interrupt controller). Implement this behaviour for the
ICV_ registers which are simple accessors to the underlying
register state.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1483977924-14522-10-git-send-email-peter.maydell@linaro.org
---
 hw/intc/arm_gicv3_cpuif.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/intc/trace-events      |  10 ++
 2 files changed, 249 insertions(+)

diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index 585c91c..40a52ce 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -13,6 +13,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/bitops.h"
 #include "trace.h"
 #include "gicv3_internal.h"
 #include "cpu.h"
@@ -48,6 +49,26 @@ static int ich_lr_state(uint64_t lr)
     return extract64(lr, ICH_LR_EL2_STATE_SHIFT, ICH_LR_EL2_STATE_LENGTH);
 }
 
+static bool icv_access(CPUARMState *env, int hcr_flags)
+{
+    /* Return true if this ICC_ register access should really be
+     * directed to an ICV_ access. hcr_flags is a mask of
+     * HCR_EL2 bits to check: we treat this as an ICV_ access
+     * if we are in NS EL1 and at least one of the specified
+     * HCR_EL2 bits is set.
+     *
+     * ICV registers fall into four categories:
+     *  * access if NS EL1 and HCR_EL2.FMO == 1:
+     *    all ICV regs with '0' in their name
+     *  * access if NS EL1 and HCR_EL2.IMO == 1:
+     *    all ICV regs with '1' in their name
+     *  * access if NS EL1 and either IMO or FMO == 1:
+     *    CTLR, DIR, PMR, RPR
+     */
+    return (env->cp15.hcr_el2 & hcr_flags) && arm_current_el(env) == 1
+        && !arm_is_secure_below_el3(env);
+}
+
 static int read_vbpr(GICv3CPUState *cs, int grp)
 {
     /* Read VBPR value out of the VMCR field (caller must handle
@@ -84,6 +105,16 @@ static void write_vbpr(GICv3CPUState *cs, int grp, int value)
     }
 }
 
+static uint32_t icv_fullprio_mask(GICv3CPUState *cs)
+{
+    /* Return a mask word which clears the unimplemented priority bits
+     * from a priority value for a virtual interrupt. (Not to be confused
+     * with the group priority, whose mask depends on the value of VBPR
+     * for the interrupt group.)
+     */
+    return ~0U << (8 - cs->vpribits);
+}
+
 static uint32_t eoi_maintenance_interrupt_state(GICv3CPUState *cs,
                                                 uint32_t *misr)
 {
@@ -168,6 +199,170 @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
 {
 }
 
+static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int regno = ri->opc2 & 3;
+    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
+    uint64_t value = cs->ich_apr[grp][regno];
+
+    trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int regno = ri->opc2 & 3;
+    int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
+
+    trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
+
+    cs->ich_apr[grp][regno] = value & 0xFFFFFFFFU;
+
+    gicv3_cpuif_virt_update(cs);
+    return;
+}
+
+static uint64_t icv_bpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1NS;
+    uint64_t bpr;
+    bool satinc = false;
+
+    if (grp == GICV3_G1NS && (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
+        /* reads return bpr0 + 1 saturated to 7, writes ignored */
+        grp = GICV3_G0;
+        satinc = true;
+    }
+
+    bpr = read_vbpr(cs, grp);
+
+    if (satinc) {
+        bpr++;
+        bpr = MIN(bpr, 7);
+    }
+
+    trace_gicv3_icv_bpr_read(ri->crm == 8 ? 0 : 1, gicv3_redist_affid(cs), bpr);
+
+    return bpr;
+}
+
+static void icv_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1NS;
+
+    trace_gicv3_icv_bpr_write(ri->crm == 8 ? 0 : 1,
+                              gicv3_redist_affid(cs), value);
+
+    if (grp == GICV3_G1NS && (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
+        /* reads return bpr0 + 1 saturated to 7, writes ignored */
+        return;
+    }
+
+    write_vbpr(cs, grp, value);
+
+    gicv3_cpuif_virt_update(cs);
+}
+
+static uint64_t icv_pmr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value;
+
+    value = extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VPMR_SHIFT,
+                      ICH_VMCR_EL2_VPMR_LENGTH);
+
+    trace_gicv3_icv_pmr_read(gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static void icv_pmr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+
+    trace_gicv3_icv_pmr_write(gicv3_redist_affid(cs), value);
+
+    value &= icv_fullprio_mask(cs);
+
+    cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VPMR_SHIFT,
+                                 ICH_VMCR_EL2_VPMR_LENGTH, value);
+
+    gicv3_cpuif_virt_update(cs);
+}
+
+static uint64_t icv_igrpen_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int enbit;
+    uint64_t value;
+
+    enbit = ri->opc2 & 1 ? ICH_VMCR_EL2_VENG1_SHIFT : ICH_VMCR_EL2_VENG0_SHIFT;
+    value = extract64(cs->ich_vmcr_el2, enbit, 1);
+
+    trace_gicv3_icv_igrpen_read(ri->opc2 & 1 ? 1 : 0,
+                                gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static void icv_igrpen_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int enbit;
+
+    trace_gicv3_icv_igrpen_write(ri->opc2 & 1 ? 1 : 0,
+                                 gicv3_redist_affid(cs), value);
+
+    enbit = ri->opc2 & 1 ? ICH_VMCR_EL2_VENG1_SHIFT : ICH_VMCR_EL2_VENG0_SHIFT;
+
+    cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, enbit, 1, value);
+    gicv3_cpuif_virt_update(cs);
+}
+
+static uint64_t icv_ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    uint64_t value;
+
+    /* Note that the fixed fields here (A3V, SEIS, IDbits, PRIbits)
+     * should match the ones reported in ich_vtr_read().
+     */
+    value = ICC_CTLR_EL1_A3V | (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
+        (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
+
+    if (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM) {
+        value |= ICC_CTLR_EL1_EOIMODE;
+    }
+
+    if (cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) {
+        value |= ICC_CTLR_EL1_CBPR;
+    }
+
+    trace_gicv3_icv_ctlr_read(gicv3_redist_affid(cs), value);
+    return value;
+}
+
+static void icv_ctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                               uint64_t value)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+
+    trace_gicv3_icv_ctlr_write(gicv3_redist_affid(cs), value);
+
+    cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VCBPR_SHIFT,
+                                 1, value & ICC_CTLR_EL1_CBPR ? 1 : 0);
+    cs->ich_vmcr_el2 = deposit64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VEOIM_SHIFT,
+                                 1, value & ICC_CTLR_EL1_EOIMODE ? 1 : 0);
+
+    gicv3_cpuif_virt_update(cs);
+}
+
 static int icc_highest_active_prio(GICv3CPUState *cs)
 {
     /* Calculate the current running priority based on the set bits
@@ -309,6 +504,10 @@ static uint64_t icc_pmr_read(CPUARMState *env, const ARMCPRegInfo *ri)
     GICv3CPUState *cs = icc_cs_from_env(env);
     uint32_t value = cs->icc_pmr_el1;
 
+    if (icv_access(env, HCR_FMO | HCR_IMO)) {
+        return icv_pmr_read(env, ri);
+    }
+
     if (arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env) &&
         (env->cp15.scr_el3 & SCR_FIQ)) {
         /* NS access and Group 0 is inaccessible to NS: return the
@@ -332,6 +531,10 @@ static void icc_pmr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 {
     GICv3CPUState *cs = icc_cs_from_env(env);
 
+    if (icv_access(env, HCR_FMO | HCR_IMO)) {
+        return icv_pmr_write(env, ri, value);
+    }
+
     trace_gicv3_icc_pmr_write(gicv3_redist_affid(cs), value);
 
     value &= 0xff;
@@ -650,6 +853,10 @@ static uint64_t icc_bpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
     bool satinc = false;
     uint64_t bpr;
 
+    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
+        return icv_bpr_read(env, ri);
+    }
+
     if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
         grp = GICV3_G1NS;
     }
@@ -686,6 +893,11 @@ static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     GICv3CPUState *cs = icc_cs_from_env(env);
     int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1;
 
+    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
+        icv_bpr_write(env, ri, value);
+        return;
+    }
+
     trace_gicv3_icc_bpr_write(ri->crm == 8 ? 0 : 1,
                               gicv3_redist_affid(cs), value);
 
@@ -719,6 +931,10 @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
     int regno = ri->opc2 & 3;
     int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
 
+    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
+        return icv_ap_read(env, ri);
+    }
+
     if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
         grp = GICV3_G1NS;
     }
@@ -737,6 +953,11 @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
     int regno = ri->opc2 & 3;
     int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
 
+    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
+        icv_ap_write(env, ri, value);
+        return;
+    }
+
     trace_gicv3_icc_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
 
     if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
@@ -949,6 +1170,10 @@ static uint64_t icc_igrpen_read(CPUARMState *env, const ARMCPRegInfo *ri)
     int grp = ri->opc2 & 1 ? GICV3_G1 : GICV3_G0;
     uint64_t value;
 
+    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
+        return icv_igrpen_read(env, ri);
+    }
+
     if (grp == GICV3_G1 && gicv3_use_ns_bank(env)) {
         grp = GICV3_G1NS;
     }
@@ -965,6 +1190,11 @@ static void icc_igrpen_write(CPUARMState *env, const ARMCPRegInfo *ri,
     GICv3CPUState *cs = icc_cs_from_env(env);
     int grp = ri->opc2 & 1 ? GICV3_G1 : GICV3_G0;
 
+    if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
+        icv_igrpen_write(env, ri, value);
+        return;
+    }
+
     trace_gicv3_icc_igrpen_write(ri->opc2 & 1 ? 1 : 0,
                                  gicv3_redist_affid(cs), value);
 
@@ -1006,6 +1236,10 @@ static uint64_t icc_ctlr_el1_read(CPUARMState *env, const ARMCPRegInfo *ri)
     int bank = gicv3_use_ns_bank(env) ? GICV3_NS : GICV3_S;
     uint64_t value;
 
+    if (icv_access(env, HCR_FMO | HCR_IMO)) {
+        return icv_ctlr_read(env, ri);
+    }
+
     value = cs->icc_ctlr_el1[bank];
     trace_gicv3_icc_ctlr_read(gicv3_redist_affid(cs), value);
     return value;
@@ -1018,6 +1252,11 @@ static void icc_ctlr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
     int bank = gicv3_use_ns_bank(env) ? GICV3_NS : GICV3_S;
     uint64_t mask;
 
+    if (icv_access(env, HCR_FMO | HCR_IMO)) {
+        icv_ctlr_write(env, ri, value);
+        return;
+    }
+
     trace_gicv3_icc_ctlr_write(gicv3_redist_affid(cs), value);
 
     /* Only CBPR and EOIMODE can be RW;
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 4ac1ea2..19fe1d5 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -123,6 +123,16 @@ gicv3_ich_vtr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_VTR read cpu %x value
 gicv3_ich_misr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_MISR read cpu %x value 0x%" PRIx64
 gicv3_ich_eisr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_EISR read cpu %x value 0x%" PRIx64
 gicv3_ich_elrsr_read(uint32_t cpu, uint64_t val) "GICv3 ICH_ELRSR read cpu %x value 0x%" PRIx64
+gicv3_icv_ap_read(int grp, int regno, uint32_t cpu, uint64_t val) "GICv3 ICV_AP%dR%d read cpu %x value 0x%" PRIx64
+gicv3_icv_ap_write(int grp, int regno, uint32_t cpu, uint64_t val) "GICv3 ICV_AP%dR%d write cpu %x value 0x%" PRIx64
+gicv3_icv_bpr_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_BPR%d read cpu %x value 0x%" PRIx64
+gicv3_icv_bpr_write(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_BPR%d write cpu %x value 0x%" PRIx64
+gicv3_icv_pmr_read(uint32_t cpu, uint64_t val) "GICv3 ICV_PMR read cpu %x value 0x%" PRIx64
+gicv3_icv_pmr_write(uint32_t cpu, uint64_t val) "GICv3 ICV_PMR write cpu %x value 0x%" PRIx64
+gicv3_icv_igrpen_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_IGRPEN%d read cpu %x value 0x%" PRIx64
+gicv3_icv_igrpen_write(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_IGRPEN%d write cpu %x value 0x%" PRIx64
+gicv3_icv_ctlr_read(uint32_t cpu, uint64_t val) "GICv3 ICV_CTLR read cpu %x value 0x%" PRIx64
+gicv3_icv_ctlr_write(uint32_t cpu, uint64_t val) "GICv3 ICV_CTLR write cpu %x value 0x%" PRIx64
 
 # hw/intc/arm_gicv3_dist.c
 gicv3_dist_read(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-- 
2.7.4

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

* [Qemu-devel] [PULL 28/36] hw/intc/arm_gicv3: Implement ICV_ HPPIR, DIR and RPR registers
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (26 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 27/36] hw/intc/arm_gicv3: Implement ICV_ registers which are just accessors Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 29/36] hw/intc/arm_gicv3: Implement ICV_ registers EOIR and IAR Peter Maydell
                   ` (7 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Implement the the ICV_ registers HPPIR, DIR and RPR.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1483977924-14522-11-git-send-email-peter.maydell@linaro.org
---
 hw/intc/arm_gicv3_cpuif.c | 235 +++++++++++++++++++++++++++++++++++++++++++++-
 hw/intc/trace-events      |   3 +
 2 files changed, 235 insertions(+), 3 deletions(-)

diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index 40a52ce..e069082 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -44,6 +44,21 @@ static inline int icv_min_vbpr(GICv3CPUState *cs)
 }
 
 /* Simple accessor functions for LR fields */
+static uint32_t ich_lr_vintid(uint64_t lr)
+{
+    return extract64(lr, ICH_LR_EL2_VINTID_SHIFT, ICH_LR_EL2_VINTID_LENGTH);
+}
+
+static uint32_t ich_lr_pintid(uint64_t lr)
+{
+    return extract64(lr, ICH_LR_EL2_PINTID_SHIFT, ICH_LR_EL2_PINTID_LENGTH);
+}
+
+static uint32_t ich_lr_prio(uint64_t lr)
+{
+    return extract64(lr, ICH_LR_EL2_PRIORITY_SHIFT, ICH_LR_EL2_PRIORITY_LENGTH);
+}
+
 static int ich_lr_state(uint64_t lr)
 {
     return extract64(lr, ICH_LR_EL2_STATE_SHIFT, ICH_LR_EL2_STATE_LENGTH);
@@ -115,6 +130,79 @@ static uint32_t icv_fullprio_mask(GICv3CPUState *cs)
     return ~0U << (8 - cs->vpribits);
 }
 
+static int ich_highest_active_virt_prio(GICv3CPUState *cs)
+{
+    /* Calculate the current running priority based on the set bits
+     * in the ICH Active Priority Registers.
+     */
+    int i;
+    int aprmax = 1 << (cs->vprebits - 5);
+
+    assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
+
+    for (i = 0; i < aprmax; i++) {
+        uint32_t apr = cs->ich_apr[GICV3_G0][i] |
+            cs->ich_apr[GICV3_G1NS][i];
+
+        if (!apr) {
+            continue;
+        }
+        return (i * 32 + ctz32(apr)) << (icv_min_vbpr(cs) + 1);
+    }
+    /* No current active interrupts: return idle priority */
+    return 0xff;
+}
+
+static int hppvi_index(GICv3CPUState *cs)
+{
+    /* Return the list register index of the highest priority pending
+     * virtual interrupt, as per the HighestPriorityVirtualInterrupt
+     * pseudocode. If no pending virtual interrupts, return -1.
+     */
+    int idx = -1;
+    int i;
+    /* Note that a list register entry with a priority of 0xff will
+     * never be reported by this function; this is the architecturally
+     * correct behaviour.
+     */
+    int prio = 0xff;
+
+    if (!(cs->ich_vmcr_el2 & (ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1))) {
+        /* Both groups disabled, definitely nothing to do */
+        return idx;
+    }
+
+    for (i = 0; i < cs->num_list_regs; i++) {
+        uint64_t lr = cs->ich_lr_el2[i];
+        int thisprio;
+
+        if (ich_lr_state(lr) != ICH_LR_EL2_STATE_PENDING) {
+            /* Not Pending */
+            continue;
+        }
+
+        /* Ignore interrupts if relevant group enable not set */
+        if (lr & ICH_LR_EL2_GROUP) {
+            if (!(cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
+                continue;
+            }
+        } else {
+            if (!(cs->ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
+                continue;
+            }
+        }
+
+        thisprio = ich_lr_prio(lr);
+
+        if (thisprio < prio) {
+            prio = thisprio;
+            idx = i;
+        }
+    }
+
+    return idx;
+}
+
 static uint32_t eoi_maintenance_interrupt_state(GICv3CPUState *cs,
                                                 uint32_t *misr)
 {
@@ -363,6 +451,35 @@ static void icv_ctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     gicv3_cpuif_virt_update(cs);
 }
 
+static uint64_t icv_rpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int prio = ich_highest_active_virt_prio(cs);
+
+    trace_gicv3_icv_rpr_read(gicv3_redist_affid(cs), prio);
+    return prio;
+}
+
+static uint64_t icv_hppir_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int grp = ri->crm == 8 ? GICV3_G0 : GICV3_G1NS;
+    int idx = hppvi_index(cs);
+    uint64_t value = INTID_SPURIOUS;
+
+    if (idx >= 0) {
+        uint64_t lr = cs->ich_lr_el2[idx];
+        int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
+
+        if (grp == thisgrp) {
+            value = ich_lr_vintid(lr);
+        }
+    }
+
+    trace_gicv3_icv_hppir_read(grp, gicv3_redist_affid(cs), value);
+    return value;
+}
+
 static int icc_highest_active_prio(GICv3CPUState *cs)
 {
     /* Calculate the current running priority based on the set bits
@@ -781,6 +898,97 @@ static void icc_deactivate_irq(GICv3CPUState *cs, int irq)
     }
 }
 
+static bool icv_eoi_split(CPUARMState *env, GICv3CPUState *cs)
+{
+    /* Return true if we should split priority drop and interrupt
+     * deactivation, ie whether the virtual EOIMode bit is set.
+     */
+    return cs->ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM;
+}
+
+static int icv_find_active(GICv3CPUState *cs, int irq)
+{
+    /* Given an interrupt number for an active interrupt, return the index
+     * of the corresponding list register, or -1 if there is no match.
+     * Corresponds to FindActiveVirtualInterrupt pseudocode.
+     */
+    int i;
+
+    for (i = 0; i < cs->num_list_regs; i++) {
+        uint64_t lr = cs->ich_lr_el2[i];
+
+        if ((lr & ICH_LR_EL2_STATE_ACTIVE_BIT) && ich_lr_vintid(lr) == irq) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+static void icv_deactivate_irq(GICv3CPUState *cs, int idx)
+{
+    /* Deactivate the interrupt in the specified list register index */
+    uint64_t lr = cs->ich_lr_el2[idx];
+
+    if (lr & ICH_LR_EL2_HW) {
+        /* Deactivate the associated physical interrupt */
+        int pirq = ich_lr_pintid(lr);
+
+        if (pirq < INTID_SECURE) {
+            icc_deactivate_irq(cs, pirq);
+        }
+    }
+
+    /* Clear the 'active' part of the state, so ActivePending->Pending
+     * and Active->Invalid.
+     */
+    lr &= ~ICH_LR_EL2_STATE_ACTIVE_BIT;
+    cs->ich_lr_el2[idx] = lr;
+}
+
+static void icv_increment_eoicount(GICv3CPUState *cs)
+{
+    /* Increment the EOICOUNT field in ICH_HCR_EL2 */
+    int eoicount = extract64(cs->ich_hcr_el2, ICH_HCR_EL2_EOICOUNT_SHIFT,
+                             ICH_HCR_EL2_EOICOUNT_LENGTH);
+
+    cs->ich_hcr_el2 = deposit64(cs->ich_hcr_el2, ICH_HCR_EL2_EOICOUNT_SHIFT,
+                                ICH_HCR_EL2_EOICOUNT_LENGTH, eoicount + 1);
+}
+
+static void icv_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t value)
+{
+    /* Deactivate interrupt */
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int idx;
+    int irq = value & 0xffffff;
+
+    trace_gicv3_icv_dir_write(gicv3_redist_affid(cs), value);
+
+    if (irq >= cs->gic->num_irq) {
+        /* Also catches special interrupt numbers and LPIs */
+        return;
+    }
+
+    if (!icv_eoi_split(env, cs)) {
+        return;
+    }
+
+    idx = icv_find_active(cs, irq);
+
+    if (idx < 0) {
+        /* No list register matching this, so increment the EOI count
+         * (might trigger a maintenance interrupt)
+         */
+        icv_increment_eoicount(cs);
+    } else {
+        icv_deactivate_irq(cs, idx);
+    }
+
+    gicv3_cpuif_virt_update(cs);
+}
+
 static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
                            uint64_t value)
 {
@@ -831,8 +1039,13 @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static uint64_t icc_hppir0_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t value = icc_hppir0_value(cs, env);
+    uint64_t value;
+
+    if (icv_access(env, HCR_FMO)) {
+        return icv_hppir_read(env, ri);
+    }
 
+    value = icc_hppir0_value(cs, env);
     trace_gicv3_icc_hppir0_read(gicv3_redist_affid(cs), value);
     return value;
 }
@@ -840,8 +1053,13 @@ static uint64_t icc_hppir0_read(CPUARMState *env, const ARMCPRegInfo *ri)
 static uint64_t icc_hppir1_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     GICv3CPUState *cs = icc_cs_from_env(env);
-    uint64_t value = icc_hppir1_value(cs, env);
+    uint64_t value;
+
+    if (icv_access(env, HCR_IMO)) {
+        return icv_hppir_read(env, ri);
+    }
 
+    value = icc_hppir1_value(cs, env);
     trace_gicv3_icc_hppir1_read(gicv3_redist_affid(cs), value);
     return value;
 }
@@ -986,6 +1204,11 @@ static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
     bool irq_is_secure, single_sec_state, irq_is_grp0;
     bool route_fiq_to_el3, route_irq_to_el3, route_fiq_to_el2, route_irq_to_el2;
 
+    if (icv_access(env, HCR_FMO | HCR_IMO)) {
+        icv_dir_write(env, ri, value);
+        return;
+    }
+
     trace_gicv3_icc_dir_write(gicv3_redist_affid(cs), value);
 
     if (irq >= cs->gic->num_irq) {
@@ -1057,7 +1280,13 @@ static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
 static uint64_t icc_rpr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     GICv3CPUState *cs = icc_cs_from_env(env);
-    int prio = icc_highest_active_prio(cs);
+    int prio;
+
+    if (icv_access(env, HCR_FMO | HCR_IMO)) {
+        return icv_rpr_read(env, ri);
+    }
+
+    prio = icc_highest_active_prio(cs);
 
     if (arm_feature(env, ARM_FEATURE_EL3) &&
         !arm_is_secure(env) && (env->cp15.scr_el3 & SCR_FIQ)) {
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 19fe1d5..fc9ec57 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -133,6 +133,9 @@ gicv3_icv_igrpen_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_IGRPEN%d r
 gicv3_icv_igrpen_write(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_IGRPEN%d write cpu %x value 0x%" PRIx64
 gicv3_icv_ctlr_read(uint32_t cpu, uint64_t val) "GICv3 ICV_CTLR read cpu %x value 0x%" PRIx64
 gicv3_icv_ctlr_write(uint32_t cpu, uint64_t val) "GICv3 ICV_CTLR write cpu %x value 0x%" PRIx64
+gicv3_icv_rpr_read(uint32_t cpu, uint64_t val) "GICv3 ICV_RPR read cpu %x value 0x%" PRIx64
+gicv3_icv_hppir_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_HPPIR%d read cpu %x value 0x%" PRIx64
+gicv3_icv_dir_write(uint32_t cpu, uint64_t val) "GICv3 ICV_DIR write cpu %x value 0x%" PRIx64
 
 # hw/intc/arm_gicv3_dist.c
 gicv3_dist_read(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-- 
2.7.4

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

* [Qemu-devel] [PULL 29/36] hw/intc/arm_gicv3: Implement ICV_ registers EOIR and IAR
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (27 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 28/36] hw/intc/arm_gicv3: Implement ICV_ HPPIR, DIR and RPR registers Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 30/36] hw/intc/arm_gicv3: Implement gicv3_cpuif_virt_update() Peter Maydell
                   ` (6 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Implement the two remaining ICV_ registers: EOIR and IAR.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1483977924-14522-12-git-send-email-peter.maydell@linaro.org
---
 hw/intc/arm_gicv3_cpuif.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++
 hw/intc/trace-events      |   2 +
 2 files changed, 222 insertions(+)

diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index e069082..f3845a6 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -203,6 +203,73 @@ static int hppvi_index(GICv3CPUState *cs)
     return idx;
 }
 
+static uint32_t icv_gprio_mask(GICv3CPUState *cs, int group)
+{
+    /* Return a mask word which clears the subpriority bits from
+     * a priority value for a virtual interrupt in the specified group.
+     * This depends on the VBPR value:
+     *  a BPR of 0 means the group priority bits are [7:1];
+     *  a BPR of 1 means they are [7:2], and so on down to
+     *  a BPR of 7 meaning no group priority bits at all.
+     * Which BPR to use depends on the group of the interrupt and
+     * the current ICH_VMCR_EL2.VCBPR settings.
+     */
+    if (group == GICV3_G1NS && cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) {
+        group = GICV3_G0;
+    }
+
+    return ~0U << (read_vbpr(cs, group) + 1);
+}
+
+static bool icv_hppi_can_preempt(GICv3CPUState *cs, uint64_t lr)
+{
+    /* Return true if we can signal this virtual interrupt defined by
+     * the given list register value; see the pseudocode functions
+     * CanSignalVirtualInterrupt and CanSignalVirtualInt.
+     * Compare also icc_hppi_can_preempt() which is the non-virtual
+     * equivalent of these checks.
+     */
+    int grp;
+    uint32_t mask, prio, rprio, vpmr;
+
+    if (!(cs->ich_hcr_el2 & ICH_HCR_EL2_EN)) {
+        /* Virtual interface disabled */
+        return false;
+    }
+
+    /* We don't need to check that this LR is in Pending state because
+     * that has already been done in hppvi_index().
+     */
+
+    prio = ich_lr_prio(lr);
+    vpmr = extract64(cs->ich_vmcr_el2, ICH_VMCR_EL2_VPMR_SHIFT,
+                     ICH_VMCR_EL2_VPMR_LENGTH);
+
+    if (prio >= vpmr) {
+        /* Priority mask masks this interrupt */
+        return false;
+    }
+
+    rprio = ich_highest_active_virt_prio(cs);
+    if (rprio == 0xff) {
+        /* No running interrupt so we can preempt */
+        return true;
+    }
+
+    grp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
+
+    mask = icv_gprio_mask(cs, grp);
+
+    /* We only preempt a running interrupt if the pending interrupt's
+     * group priority is sufficient (the subpriorities are not considered).
+     */
+    if ((prio & mask) < (rprio & mask)) {
+        return true;
+    }
+
+    return false;
+}
+
 static uint32_t eoi_maintenance_interrupt_state(GICv3CPUState *cs,
                                                 uint32_t *misr)
 {
@@ -480,6 +547,53 @@ static uint64_t icv_hppir_read(CPUARMState *env, const ARMCPRegInfo *ri)
     return value;
 }
 
+static void icv_activate_irq(GICv3CPUState *cs, int idx, int grp)
+{
+    /* Activate the interrupt in the specified list register
+     * by moving it from Pending to Active state, and update the
+     * Active Priority Registers.
+     */
+    uint32_t mask = icv_gprio_mask(cs, grp);
+    int prio = ich_lr_prio(cs->ich_lr_el2[idx]) & mask;
+    int aprbit = prio >> (8 - cs->vprebits);
+    int regno = aprbit / 32;
+    int regbit = aprbit % 32;
+
+    cs->ich_lr_el2[idx] &= ~ICH_LR_EL2_STATE_PENDING_BIT;
+    cs->ich_lr_el2[idx] |= ICH_LR_EL2_STATE_ACTIVE_BIT;
+    cs->ich_apr[grp][regno] |= (1 << regbit);
+}
+
+static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int grp = ri->crm == 8 ? GICV3_G0 : GICV3_G1NS;
+    int idx = hppvi_index(cs);
+    uint64_t intid = INTID_SPURIOUS;
+
+    if (idx >= 0) {
+        uint64_t lr = cs->ich_lr_el2[idx];
+        int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
+
+        if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) {
+            intid = ich_lr_vintid(lr);
+            if (intid < INTID_SECURE) {
+                icv_activate_irq(cs, idx, grp);
+            } else {
+                /* Interrupt goes from Pending to Invalid */
+                cs->ich_lr_el2[idx] &= ~ICH_LR_EL2_STATE_PENDING_BIT;
+                /* We will now return the (bogus) ID from the list register,
+                 * as per the pseudocode.
+                 */
+            }
+        }
+    }
+
+    trace_gicv3_icv_iar_read(ri->crm == 8 ? 0 : 1,
+                             gicv3_redist_affid(cs), intid);
+    return intid;
+}
+
 static int icc_highest_active_prio(GICv3CPUState *cs)
 {
     /* Calculate the current running priority based on the set bits
@@ -773,6 +887,10 @@ static uint64_t icc_iar0_read(CPUARMState *env, const ARMCPRegInfo *ri)
     GICv3CPUState *cs = icc_cs_from_env(env);
     uint64_t intid;
 
+    if (icv_access(env, HCR_FMO)) {
+        return icv_iar_read(env, ri);
+    }
+
     if (!icc_hppi_can_preempt(cs)) {
         intid = INTID_SPURIOUS;
     } else {
@@ -792,6 +910,10 @@ static uint64_t icc_iar1_read(CPUARMState *env, const ARMCPRegInfo *ri)
     GICv3CPUState *cs = icc_cs_from_env(env);
     uint64_t intid;
 
+    if (icv_access(env, HCR_IMO)) {
+        return icv_iar_read(env, ri);
+    }
+
     if (!icc_hppi_can_preempt(cs)) {
         intid = INTID_SPURIOUS;
     } else {
@@ -956,6 +1078,48 @@ static void icv_increment_eoicount(GICv3CPUState *cs)
                                 ICH_HCR_EL2_EOICOUNT_LENGTH, eoicount + 1);
 }
 
+static int icv_drop_prio(GICv3CPUState *cs)
+{
+    /* Drop the priority of the currently active virtual interrupt
+     * (favouring group 0 if there is a set active bit at
+     * the same priority for both group 0 and group 1).
+     * Return the priority value for the bit we just cleared,
+     * or 0xff if no bits were set in the AP registers at all.
+     * Note that though the ich_apr[] are uint64_t only the low
+     * 32 bits are actually relevant.
+     */
+    int i;
+    int aprmax = 1 << (cs->vprebits - 5);
+
+    assert(aprmax <= ARRAY_SIZE(cs->ich_apr[0]));
+
+    for (i = 0; i < aprmax; i++) {
+        uint64_t *papr0 = &cs->ich_apr[GICV3_G0][i];
+        uint64_t *papr1 = &cs->ich_apr[GICV3_G1NS][i];
+        int apr0count, apr1count;
+
+        if (!*papr0 && !*papr1) {
+            continue;
+        }
+
+        /* We can't just use the bit-twiddling hack icc_drop_prio() does
+         * because we need to return the bit number we cleared so
+         * it can be compared against the list register's priority field.
+         */
+        apr0count = ctz32(*papr0);
+        apr1count = ctz32(*papr1);
+
+        if (apr0count <= apr1count) {
+            *papr0 &= *papr0 - 1;
+            return (apr0count + i * 32) << (icv_min_vbpr(cs) + 1);
+        } else {
+            *papr1 &= *papr1 - 1;
+            return (apr1count + i * 32) << (icv_min_vbpr(cs) + 1);
+        }
+    }
+    return 0xff;
+}
+
 static void icv_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
                           uint64_t value)
 {
@@ -989,6 +1153,57 @@ static void icv_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
     gicv3_cpuif_virt_update(cs);
 }
 
+static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                           uint64_t value)
+{
+    /* End of Interrupt */
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int irq = value & 0xffffff;
+    int grp = ri->crm == 8 ? GICV3_G0 : GICV3_G1NS;
+    int idx, dropprio;
+
+    trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1,
+                               gicv3_redist_affid(cs), value);
+
+    if (irq >= cs->gic->num_irq) {
+        /* Also catches special interrupt numbers and LPIs */
+        return;
+    }
+
+    /* We implement the IMPDEF choice of "drop priority before doing
+     * error checks" (because that lets us avoid scanning the AP
+     * registers twice).
+     */
+    dropprio = icv_drop_prio(cs);
+    if (dropprio == 0xff) {
+        /* No active interrupt. It is CONSTRAINED UNPREDICTABLE
+         * whether the list registers are checked in this
+         * situation; we choose not to.
+         */
+        return;
+    }
+
+    idx = icv_find_active(cs, irq);
+
+    if (idx < 0) {
+        /* No valid list register corresponding to EOI ID */
+        icv_increment_eoicount(cs);
+    } else {
+        uint64_t lr = cs->ich_lr_el2[idx];
+        int thisgrp = (lr & ICH_LR_EL2_GROUP) ? GICV3_G1NS : GICV3_G0;
+        int lr_gprio = ich_lr_prio(lr) & icv_gprio_mask(cs, grp);
+
+        if (thisgrp == grp && lr_gprio == dropprio) {
+            if (!icv_eoi_split(env, cs)) {
+                /* Priority drop and deactivate not split: deactivate irq now */
+                icv_deactivate_irq(cs, idx);
+            }
+        }
+    }
+
+    gicv3_cpuif_virt_update(cs);
+}
+
 static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
                            uint64_t value)
 {
@@ -997,6 +1212,11 @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
     int irq = value & 0xffffff;
     int grp;
 
+    if (icv_access(env, ri->crm == 8 ? HCR_FMO : HCR_IMO)) {
+        icv_eoir_write(env, ri, value);
+        return;
+    }
+
     trace_gicv3_icc_eoir_write(ri->crm == 8 ? 0 : 1,
                                gicv3_redist_affid(cs), value);
 
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index fc9ec57..1dcc830 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -136,6 +136,8 @@ gicv3_icv_ctlr_write(uint32_t cpu, uint64_t val) "GICv3 ICV_CTLR write cpu %x va
 gicv3_icv_rpr_read(uint32_t cpu, uint64_t val) "GICv3 ICV_RPR read cpu %x value 0x%" PRIx64
 gicv3_icv_hppir_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_HPPIR%d read cpu %x value 0x%" PRIx64
 gicv3_icv_dir_write(uint32_t cpu, uint64_t val) "GICv3 ICV_DIR write cpu %x value 0x%" PRIx64
+gicv3_icv_iar_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_IAR%d read cpu %x value 0x%" PRIx64
+gicv3_icv_eoir_write(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_EOIR%d write cpu %x value 0x%" PRIx64
 
 # hw/intc/arm_gicv3_dist.c
 gicv3_dist_read(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-- 
2.7.4

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

* [Qemu-devel] [PULL 30/36] hw/intc/arm_gicv3: Implement gicv3_cpuif_virt_update()
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (28 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 29/36] hw/intc/arm_gicv3: Implement ICV_ registers EOIR and IAR Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 31/36] hw/intc/arm_gicv3: Implement EL2 traps for CPU i/f regs Peter Maydell
                   ` (5 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Implement the function which signals virtual interrupts to the
CPU as appropriate following CPU interface state changes.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1483977924-14522-13-git-send-email-peter.maydell@linaro.org
---
 include/hw/intc/arm_gicv3_common.h |  1 +
 hw/intc/arm_gicv3_cpuif.c          | 49 ++++++++++++++++++++++++++++++++++++++
 hw/intc/trace-events               |  2 ++
 3 files changed, 52 insertions(+)

diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
index 665d3f8..4156051 100644
--- a/include/hw/intc/arm_gicv3_common.h
+++ b/include/hw/intc/arm_gicv3_common.h
@@ -150,6 +150,7 @@ struct GICv3CPUState {
     qemu_irq parent_fiq;
     qemu_irq parent_virq;
     qemu_irq parent_vfiq;
+    qemu_irq maintenance_irq;
 
     /* Redistributor */
     uint32_t level;                  /* Current IRQ level */
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index f3845a6..e05f6b3 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -352,6 +352,53 @@ static uint32_t maintenance_interrupt_state(GICv3CPUState *cs)
 
 static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
 {
+    /* Tell the CPU about any pending virtual interrupts or
+     * maintenance interrupts, following a change to the state
+     * of the CPU interface relevant to virtual interrupts.
+     *
+     * CAUTION: this function will call qemu_set_irq() on the
+     * CPU maintenance IRQ line, which is typically wired up
+     * to the GIC as a per-CPU interrupt. This means that it
+     * will recursively call back into the GIC code via
+     * gicv3_redist_set_irq() and thus into the CPU interface code's
+     * gicv3_cpuif_update(). It is therefore important that this
+     * function is only called as the final action of a CPU interface
+     * register write implementation, after all the GIC state
+     * fields have been updated. gicv3_cpuif_update() also must
+     * not cause this function to be called, but that happens
+     * naturally as a result of there being no architectural
+     * linkage between the physical and virtual GIC logic.
+     */
+    int idx;
+    int irqlevel = 0;
+    int fiqlevel = 0;
+    int maintlevel = 0;
+
+    idx = hppvi_index(cs);
+    trace_gicv3_cpuif_virt_update(gicv3_redist_affid(cs), idx);
+    if (idx >= 0) {
+        uint64_t lr = cs->ich_lr_el2[idx];
+
+        if (icv_hppi_can_preempt(cs, lr)) {
+            /* Virtual interrupts are simple: G0 are always FIQ, and G1 IRQ */
+            if (lr & ICH_LR_EL2_GROUP) {
+                irqlevel = 1;
+            } else {
+                fiqlevel = 1;
+            }
+        }
+    }
+
+    if (cs->ich_hcr_el2 & ICH_HCR_EL2_EN) {
+        maintlevel = maintenance_interrupt_state(cs);
+    }
+
+    trace_gicv3_cpuif_virt_set_irqs(gicv3_redist_affid(cs), fiqlevel,
+                                    irqlevel, maintlevel);
+
+    qemu_set_irq(cs->parent_vfiq, fiqlevel);
+    qemu_set_irq(cs->parent_virq, irqlevel);
+    qemu_set_irq(cs->maintenance_irq, maintlevel);
 }
 
 static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -2480,6 +2527,8 @@ void gicv3_init_cpuif(GICv3State *s)
             && cpu->gic_num_lrs) {
             int j;
 
+            cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
+
             cs->num_list_regs = cpu->gic_num_lrs;
             cs->vpribits = cpu->gic_vpribits;
             cs->vprebits = cpu->gic_vprebits;
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 1dcc830..6116df5 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -138,6 +138,8 @@ gicv3_icv_hppir_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_HPPIR%d rea
 gicv3_icv_dir_write(uint32_t cpu, uint64_t val) "GICv3 ICV_DIR write cpu %x value 0x%" PRIx64
 gicv3_icv_iar_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_IAR%d read cpu %x value 0x%" PRIx64
 gicv3_icv_eoir_write(int grp, uint32_t cpu, uint64_t val) "GICv3 ICV_EOIR%d write cpu %x value 0x%" PRIx64
+gicv3_cpuif_virt_update(uint32_t cpuid, int idx) "GICv3 CPU i/f %x virt HPPI update LR index %d"
+gicv3_cpuif_virt_set_irqs(uint32_t cpuid, int fiqlevel, int irqlevel, int maintlevel) "GICv3 CPU i/f %x virt HPPI update: setting FIQ %d IRQ %d maintenance-irq %d"
 
 # hw/intc/arm_gicv3_dist.c
 gicv3_dist_read(uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 distributor read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
-- 
2.7.4

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

* [Qemu-devel] [PULL 31/36] hw/intc/arm_gicv3: Implement EL2 traps for CPU i/f regs
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (29 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 30/36] hw/intc/arm_gicv3: Implement gicv3_cpuif_virt_update() Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 32/36] hw/arm/virt: Support using SMC for PSCI Peter Maydell
                   ` (4 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Implement the architecturally required traps from NS EL1
to EL2 for the CPU interface registers. These fall into
several different groups:
 * group-0-only registers all trap if ICH_HRC_EL2.TALL0 is set
   (exactly the registers covered by gicv3_fiq_access())
 * group-1-only registers all trap if ICH_HRC_EL2.TALL1 is set
   (exactly the registers covered by gicv3_irq_access())
 * DIR traps if ICH_HCR_EL2.TC or ICH_HCR_EL2.TDIR are set
 * PMR, RPR, CTLR trap if ICH_HCR_EL2.TC is set
 * SGI0R, SGI1R, ASGI1R trap if ICH_HCR_EL2.TC is set or
   if HCR_EL2.IMO or HCR_EL2.FMO are set

We split DIR and the SGI registers out into their own access
functions, leaving the existing gicv3_irqfiq_access() just
handling PMR, RPR and CTLR.

This commit doesn't implement support for trapping on
HSTR_EL2.T12 for the 32-bit registers, as we don't implement
any of those per-coprocessor trap bits currently and
probably will want to do those in some more centralized way.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1483977924-14522-14-git-send-email-peter.maydell@linaro.org
---
 hw/intc/arm_gicv3_cpuif.c | 70 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 60 insertions(+), 10 deletions(-)

diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index e05f6b3..a9ee7fd 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -1833,9 +1833,17 @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env,
                                           const ARMCPRegInfo *ri, bool isread)
 {
     CPAccessResult r = CP_ACCESS_OK;
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int el = arm_current_el(env);
+
+    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_TC) &&
+        el == 1 && !arm_is_secure_below_el3(env)) {
+        /* Takes priority over a possible EL3 trap */
+        return CP_ACCESS_TRAP_EL2;
+    }
 
     if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) {
-        switch (arm_current_el(env)) {
+        switch (el) {
         case 1:
             if (arm_is_secure_below_el3(env) ||
                 ((env->cp15.hcr_el2 & (HCR_IMO | HCR_FMO)) == 0)) {
@@ -1861,13 +1869,47 @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env,
     return r;
 }
 
+static CPAccessResult gicv3_dir_access(CPUARMState *env,
+                                       const ARMCPRegInfo *ri, bool isread)
+{
+    GICv3CPUState *cs = icc_cs_from_env(env);
+
+    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_TDIR) &&
+        arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) {
+        /* Takes priority over a possible EL3 trap */
+        return CP_ACCESS_TRAP_EL2;
+    }
+
+    return gicv3_irqfiq_access(env, ri, isread);
+}
+
+static CPAccessResult gicv3_sgi_access(CPUARMState *env,
+                                       const ARMCPRegInfo *ri, bool isread)
+{
+    if ((env->cp15.hcr_el2 & (HCR_IMO | HCR_FMO)) &&
+        arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) {
+        /* Takes priority over a possible EL3 trap */
+        return CP_ACCESS_TRAP_EL2;
+    }
+
+    return gicv3_irqfiq_access(env, ri, isread);
+}
+
 static CPAccessResult gicv3_fiq_access(CPUARMState *env,
                                        const ARMCPRegInfo *ri, bool isread)
 {
     CPAccessResult r = CP_ACCESS_OK;
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int el = arm_current_el(env);
+
+    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_TALL0) &&
+        el == 1 && !arm_is_secure_below_el3(env)) {
+        /* Takes priority over a possible EL3 trap */
+        return CP_ACCESS_TRAP_EL2;
+    }
 
     if (env->cp15.scr_el3 & SCR_FIQ) {
-        switch (arm_current_el(env)) {
+        switch (el) {
         case 1:
             if (arm_is_secure_below_el3(env) ||
                 ((env->cp15.hcr_el2 & HCR_FMO) == 0)) {
@@ -1897,9 +1939,17 @@ static CPAccessResult gicv3_irq_access(CPUARMState *env,
                                        const ARMCPRegInfo *ri, bool isread)
 {
     CPAccessResult r = CP_ACCESS_OK;
+    GICv3CPUState *cs = icc_cs_from_env(env);
+    int el = arm_current_el(env);
+
+    if ((cs->ich_hcr_el2 & ICH_HCR_EL2_TALL1) &&
+        el == 1 && !arm_is_secure_below_el3(env)) {
+        /* Takes priority over a possible EL3 trap */
+        return CP_ACCESS_TRAP_EL2;
+    }
 
     if (env->cp15.scr_el3 & SCR_IRQ) {
-        switch (arm_current_el(env)) {
+        switch (el) {
         case 1:
             if (arm_is_secure_below_el3(env) ||
                 ((env->cp15.hcr_el2 & HCR_IMO) == 0)) {
@@ -2055,7 +2105,7 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
     { .name = "ICC_DIR_EL1", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 1,
       .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
+      .access = PL1_W, .accessfn = gicv3_dir_access,
       .writefn = icc_dir_write,
     },
     { .name = "ICC_RPR_EL1", .state = ARM_CP_STATE_BOTH,
@@ -2067,37 +2117,37 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
     { .name = "ICC_SGI1R_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 5,
       .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
+      .access = PL1_W, .accessfn = gicv3_sgi_access,
       .writefn = icc_sgi1r_write,
     },
     { .name = "ICC_SGI1R",
       .cp = 15, .opc1 = 0, .crm = 12,
       .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
+      .access = PL1_W, .accessfn = gicv3_sgi_access,
       .writefn = icc_sgi1r_write,
     },
     { .name = "ICC_ASGI1R_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 6,
       .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
+      .access = PL1_W, .accessfn = gicv3_sgi_access,
       .writefn = icc_asgi1r_write,
     },
     { .name = "ICC_ASGI1R",
       .cp = 15, .opc1 = 1, .crm = 12,
       .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
+      .access = PL1_W, .accessfn = gicv3_sgi_access,
       .writefn = icc_asgi1r_write,
     },
     { .name = "ICC_SGI0R_EL1", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 11, .opc2 = 7,
       .type = ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
+      .access = PL1_W, .accessfn = gicv3_sgi_access,
       .writefn = icc_sgi0r_write,
     },
     { .name = "ICC_SGI0R",
       .cp = 15, .opc1 = 2, .crm = 12,
       .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_NO_RAW,
-      .access = PL1_W, .accessfn = gicv3_irqfiq_access,
+      .access = PL1_W, .accessfn = gicv3_sgi_access,
       .writefn = icc_sgi0r_write,
     },
     { .name = "ICC_IAR1_EL1", .state = ARM_CP_STATE_BOTH,
-- 
2.7.4

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

* [Qemu-devel] [PULL 32/36] hw/arm/virt: Support using SMC for PSCI
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (30 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 31/36] hw/intc/arm_gicv3: Implement EL2 traps for CPU i/f regs Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 33/36] hw/arm/virt-acpi-build: use SMC if booting in EL2 Peter Maydell
                   ` (3 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

If we are giving the guest a CPU with EL2, it is likely to
want to use the HVC instruction itself, for instance for
providing PSCI to inner guest VMs. This makes using HVC
as the PSCI conduit for the outer QEMU a bad idea. We will
want to use SMC instead is this case: this makes sense
because QEMU's PSCI implementation is effectively an
emulation of functionality provided by EL3 firmware.

Add code to support selecting the PSCI conduit to use,
rather than hardcoding use of HVC.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Message-id: 1483977924-14522-15-git-send-email-peter.maydell@linaro.org
---
 include/hw/arm/virt.h |  2 +-
 hw/arm/virt.c         | 27 +++++++++++++++++++++------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index b8a19ec..53507e6 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -103,7 +103,7 @@ typedef struct {
     uint32_t clock_phandle;
     uint32_t gic_phandle;
     uint32_t msi_phandle;
-    bool using_psci;
+    int psci_conduit;
 } VirtMachineState;
 
 #define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("virt")
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index d931d17..3a6f895 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -229,9 +229,19 @@ static void fdt_add_psci_node(const VirtMachineState *vms)
     uint32_t migrate_fn;
     void *fdt = vms->fdt;
     ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
+    const char *psci_method;
 
-    if (!vms->using_psci) {
+    switch (vms->psci_conduit) {
+    case QEMU_PSCI_CONDUIT_DISABLED:
         return;
+    case QEMU_PSCI_CONDUIT_HVC:
+        psci_method = "hvc";
+        break;
+    case QEMU_PSCI_CONDUIT_SMC:
+        psci_method = "smc";
+        break;
+    default:
+        g_assert_not_reached();
     }
 
     qemu_fdt_add_subnode(fdt, "/psci");
@@ -263,7 +273,7 @@ static void fdt_add_psci_node(const VirtMachineState *vms)
      * However, the device tree binding uses 'method' instead, so that is
      * what we should use here.
      */
-    qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
+    qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
 
     qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
     qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
@@ -365,7 +375,8 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
         qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
                                     armcpu->dtb_compatible);
 
-        if (vms->using_psci && vms->smp_cpus > 1) {
+        if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED
+            && vms->smp_cpus > 1) {
             qemu_fdt_setprop_string(vms->fdt, nodename,
                                         "enable-method", "psci");
         }
@@ -1230,7 +1241,11 @@ static void machvirt_init(MachineState *machine)
      * let the boot ROM sort them out.
      * The usual case is that we do use QEMU's PSCI implementation.
      */
-    vms->using_psci = !(vms->secure && firmware_loaded);
+    if (vms->secure && firmware_loaded) {
+        vms->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
+    } else {
+        vms->psci_conduit = QEMU_PSCI_CONDUIT_HVC;
+    }
 
     /* The maximum number of CPUs depends on the GIC version, or on how
      * many redistributors we can fit into the memory map.
@@ -1313,8 +1328,8 @@ static void machvirt_init(MachineState *machine)
             object_property_set_bool(cpuobj, false, "has_el3", NULL);
         }
 
-        if (vms->using_psci) {
-            object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC,
+        if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) {
+            object_property_set_int(cpuobj, vms->psci_conduit,
                                     "psci-conduit", NULL);
 
             /* Secondary CPUs start in PSCI powered-down state */
-- 
2.7.4

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

* [Qemu-devel] [PULL 33/36] hw/arm/virt-acpi-build: use SMC if booting in EL2
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (31 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 32/36] hw/arm/virt: Support using SMC for PSCI Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 34/36] target/arm/psci.c: If EL2 implemented, start CPUs " Peter Maydell
                   ` (2 subsequent siblings)
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

From: Andrew Jones <drjones@redhat.com>

Signed-off-by: Andrew Jones <drjones@redhat.com>
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1483977924-14522-16-git-send-email-peter.maydell@linaro.org
[PMM: look at vms->psci_conduit rather than vms->virt
 to decide whether to use HVC or SMC, and report no
 PSCI support at all for the 'PSCI disabled' case]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt-acpi-build.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 50d52f6..73aca9e 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -650,16 +650,30 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 }
 
 /* FADT */
-static void
-build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset)
+static void build_fadt(GArray *table_data, BIOSLinker *linker,
+                       VirtMachineState *vms, unsigned dsdt_tbl_offset)
 {
     AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
     unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
+    uint16_t bootflags;
+
+    switch (vms->psci_conduit) {
+    case QEMU_PSCI_CONDUIT_DISABLED:
+        bootflags = 0;
+        break;
+    case QEMU_PSCI_CONDUIT_HVC:
+        bootflags = ACPI_FADT_ARM_PSCI_COMPLIANT | ACPI_FADT_ARM_PSCI_USE_HVC;
+        break;
+    case QEMU_PSCI_CONDUIT_SMC:
+        bootflags = ACPI_FADT_ARM_PSCI_COMPLIANT;
+        break;
+    default:
+        g_assert_not_reached();
+    }
 
-    /* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
+    /* Hardware Reduced = 1 and use PSCI 0.2+ */
     fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
-    fadt->arm_boot_flags = cpu_to_le16(ACPI_FADT_ARM_PSCI_COMPLIANT |
-                                       ACPI_FADT_ARM_PSCI_USE_HVC);
+    fadt->arm_boot_flags = cpu_to_le16(bootflags);
 
     /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
     fadt->minor_revision = 0x1;
@@ -745,7 +759,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
 
     /* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
     acpi_add_table(table_offsets, tables_blob);
-    build_fadt(tables_blob, tables->linker, dsdt);
+    build_fadt(tables_blob, tables->linker, vms, dsdt);
 
     acpi_add_table(table_offsets, tables_blob);
     build_madt(tables_blob, tables->linker, vms);
-- 
2.7.4

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

* [Qemu-devel] [PULL 34/36] target/arm/psci.c: If EL2 implemented, start CPUs in EL2
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (32 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 33/36] hw/arm/virt-acpi-build: use SMC if booting in EL2 Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 35/36] target-arm: Enable EL2 feature bit on A53 and A57 Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 36/36] hw/arm/virt: Add board property to enable EL2 Peter Maydell
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

The PSCI spec states that a CPU_ON call should cause the new
CPU to be started in the highest implemented Non-secure
exception level. We were incorrectly starting it at the
exception level of the caller, which happens to be correct
if EL2 is not implemented. Implement the correct logic
as described in the PSCI 1.0 spec section 6.4:
 * if EL2 exists and SCR_EL3.HCE is set: start in EL2
 * otherwise start in EL1

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Tested-by: Andrew Jones <drjones@redhat.com>
Message-id: 1483977924-14522-17-git-send-email-peter.maydell@linaro.org
---
 target/arm/psci.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/target/arm/psci.c b/target/arm/psci.c
index 14316eb..64bf82e 100644
--- a/target/arm/psci.c
+++ b/target/arm/psci.c
@@ -148,17 +148,28 @@ void arm_handle_psci_call(ARMCPU *cpu)
     case QEMU_PSCI_0_1_FN_CPU_ON:
     case QEMU_PSCI_0_2_FN_CPU_ON:
     case QEMU_PSCI_0_2_FN64_CPU_ON:
+    {
+        /* The PSCI spec mandates that newly brought up CPUs start
+         * in the highest exception level which exists and is enabled
+         * on the calling CPU. Since the QEMU PSCI implementation is
+         * acting as a "fake EL3" or "fake EL2" firmware, this for us
+         * means that we want to start at the highest NS exception level
+         * that we are providing to the guest.
+         * The execution mode should be that which is currently in use
+         * by the same exception level on the calling CPU.
+         * The CPU should be started with the context_id value
+         * in x0 (if AArch64) or r0 (if AArch32).
+         */
+        int target_el = arm_feature(env, ARM_FEATURE_EL2) ? 2 : 1;
+        bool target_aarch64 = arm_el_is_aa64(env, target_el);
+
         mpidr = param[1];
         entry = param[2];
         context_id = param[3];
-        /*
-         * The PSCI spec mandates that newly brought up CPUs enter the
-         * exception level of the caller in the same execution mode as
-         * the caller, with context_id in x0/r0, respectively.
-         */
-        ret = arm_set_cpu_on(mpidr, entry, context_id, arm_current_el(env),
-                             is_a64(env));
+        ret = arm_set_cpu_on(mpidr, entry, context_id,
+                             target_el, target_aarch64);
         break;
+    }
     case QEMU_PSCI_0_1_FN_CPU_OFF:
     case QEMU_PSCI_0_2_FN_CPU_OFF:
         goto cpu_off;
-- 
2.7.4

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

* [Qemu-devel] [PULL 35/36] target-arm: Enable EL2 feature bit on A53 and A57
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (33 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 34/36] target/arm/psci.c: If EL2 implemented, start CPUs " Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  2017-01-19 14:09 ` [Qemu-devel] [PULL 36/36] hw/arm/virt: Add board property to enable EL2 Peter Maydell
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Enable the ARM_FEATURE_EL2 bit on Cortex-A52 and
Cortex-A57, since this is all now sufficiently implemented
to work with the GICv3. We provide the usual CPU property
to disable it for backwards compatibility with the older
virt boards.

In this commit, we disable the EL2 feature on the
virt and ZynpMP boards, so there is no overall effect.
Another commit will expose a board-level property to
allow the user to enable EL2.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
Message-id: 1483977924-14522-18-git-send-email-peter.maydell@linaro.org
---
 target/arm/cpu.h     |  2 ++
 hw/arm/virt.c        |  4 ++++
 hw/arm/xlnx-zynqmp.c |  2 ++
 target/arm/cpu.c     | 12 ++++++++++++
 target/arm/cpu64.c   |  2 ++
 5 files changed, 22 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 16c7c10..151a5d7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -577,6 +577,8 @@ struct ARMCPU {
     bool start_powered_off;
     /* CPU currently in PSCI powered-off state */
     bool powered_off;
+    /* CPU has virtualization extension */
+    bool has_el2;
     /* CPU has security extension */
     bool has_el3;
     /* CPU has PMU (Performance Monitor Unit) */
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 3a6f895..769afa0 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1328,6 +1328,10 @@ static void machvirt_init(MachineState *machine)
             object_property_set_bool(cpuobj, false, "has_el3", NULL);
         }
 
+        if (object_property_find(cpuobj, "has_el2", NULL)) {
+            object_property_set_bool(cpuobj, false, "has_el2", NULL);
+        }
+
         if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) {
             object_property_set_int(cpuobj, vms->psci_conduit,
                                     "psci-conduit", NULL);
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 0d86ba3..bc4e66b 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -258,6 +258,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
 
         object_property_set_bool(OBJECT(&s->apu_cpu[i]),
                                  s->secure, "has_el3", NULL);
+        object_property_set_bool(OBJECT(&s->apu_cpu[i]),
+                                 false, "has_el2", NULL);
         object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
                                 "reset-cbar", &error_abort);
         object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized",
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 93ebbc9..3f2cdb6 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -496,6 +496,9 @@ static Property arm_cpu_reset_hivecs_property =
 static Property arm_cpu_rvbar_property =
             DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0);
 
+static Property arm_cpu_has_el2_property =
+            DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true);
+
 static Property arm_cpu_has_el3_property =
             DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true);
 
@@ -546,6 +549,11 @@ static void arm_cpu_post_init(Object *obj)
 #endif
     }
 
+    if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
+        qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el2_property,
+                                 &error_abort);
+    }
+
     if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
         qdev_property_add_static(DEVICE(obj), &arm_cpu_has_pmu_property,
                                  &error_abort);
@@ -694,6 +702,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
         cpu->id_aa64pfr0 &= ~0xf000;
     }
 
+    if (!cpu->has_el2) {
+        unset_feature(env, ARM_FEATURE_EL2);
+    }
+
     if (!cpu->has_pmu || !kvm_enabled()) {
         cpu->has_pmu = false;
         unset_feature(env, ARM_FEATURE_PMU);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 73c7f31..670c07a 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -110,6 +110,7 @@ static void aarch64_a57_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
     set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
     set_feature(&cpu->env, ARM_FEATURE_CRC);
+    set_feature(&cpu->env, ARM_FEATURE_EL2);
     set_feature(&cpu->env, ARM_FEATURE_EL3);
     set_feature(&cpu->env, ARM_FEATURE_PMU);
     cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
@@ -169,6 +170,7 @@ static void aarch64_a53_initfn(Object *obj)
     set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
     set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
     set_feature(&cpu->env, ARM_FEATURE_CRC);
+    set_feature(&cpu->env, ARM_FEATURE_EL2);
     set_feature(&cpu->env, ARM_FEATURE_EL3);
     set_feature(&cpu->env, ARM_FEATURE_PMU);
     cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;
-- 
2.7.4

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

* [Qemu-devel] [PULL 36/36] hw/arm/virt: Add board property to enable EL2
  2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
                   ` (34 preceding siblings ...)
  2017-01-19 14:09 ` [Qemu-devel] [PULL 35/36] target-arm: Enable EL2 feature bit on A53 and A57 Peter Maydell
@ 2017-01-19 14:09 ` Peter Maydell
  35 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-01-19 14:09 UTC (permalink / raw)
  To: qemu-devel

Add a board level property to the virt board which will
enable EL2 on the CPU if the user asks for it. The
default is not to provide EL2. If EL2 is enabled then
we will use SMC as our PSCI conduit, and report the
virtualization support in the GICv3 device tree node
and the ACPI tables.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1483977924-14522-19-git-send-email-peter.maydell@linaro.org
---
 include/hw/arm/virt.h    |  1 +
 hw/arm/virt-acpi-build.c |  3 +++
 hw/arm/virt.c            | 44 ++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 53507e6..58ce74e 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -93,6 +93,7 @@ typedef struct {
     FWCfgState *fw_cfg;
     bool secure;
     bool highmem;
+    bool virt;
     int32_t gic_version;
     struct arm_boot_info bootinfo;
     const MemMapEntry *memmap;
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 73aca9e..d0a8a0f 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -614,6 +614,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
         if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
             gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
         }
+        if (vms->virt && vms->gic_version == 3) {
+            gicc->vgic_interrupt = cpu_to_le32(PPI(ARCH_GICV3_MAINT_IRQ));
+        }
     }
 
     if (vms->gic_version == 3) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 769afa0..6c9e898 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -443,6 +443,11 @@ static void fdt_add_gic_node(VirtMachineState *vms)
                                      2, vms->memmap[VIRT_GIC_DIST].size,
                                      2, vms->memmap[VIRT_GIC_REDIST].base,
                                      2, vms->memmap[VIRT_GIC_REDIST].size);
+        if (vms->virt) {
+            qemu_fdt_setprop_cells(vms->fdt, "/intc", "interrupts",
+                                   GIC_FDT_IRQ_TYPE_PPI, ARCH_GICV3_MAINT_IRQ,
+                                   GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+        }
     } else {
         /* 'cortex-a15-gic' means 'GIC v2' */
         qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
@@ -1239,10 +1244,15 @@ static void machvirt_init(MachineState *machine)
      * so it doesn't get in the way. Instead of starting secondary
      * CPUs in PSCI powerdown state we will start them all running and
      * let the boot ROM sort them out.
-     * The usual case is that we do use QEMU's PSCI implementation.
+     * The usual case is that we do use QEMU's PSCI implementation;
+     * if the guest has EL2 then we will use SMC as the conduit,
+     * and otherwise we will use HVC (for backwards compatibility and
+     * because if we're using KVM then we must use HVC).
      */
     if (vms->secure && firmware_loaded) {
         vms->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
+    } else if (vms->virt) {
+        vms->psci_conduit = QEMU_PSCI_CONDUIT_SMC;
     } else {
         vms->psci_conduit = QEMU_PSCI_CONDUIT_HVC;
     }
@@ -1272,6 +1282,12 @@ static void machvirt_init(MachineState *machine)
         exit(1);
     }
 
+    if (vms->virt && kvm_enabled()) {
+        error_report("mach-virt: KVM does not support providing "
+                     "Virtualization extensions to the guest CPU");
+        exit(1);
+    }
+
     if (vms->secure) {
         if (kvm_enabled()) {
             error_report("mach-virt: KVM does not support Security extensions");
@@ -1328,7 +1344,7 @@ static void machvirt_init(MachineState *machine)
             object_property_set_bool(cpuobj, false, "has_el3", NULL);
         }
 
-        if (object_property_find(cpuobj, "has_el2", NULL)) {
+        if (!vms->virt && object_property_find(cpuobj, "has_el2", NULL)) {
             object_property_set_bool(cpuobj, false, "has_el2", NULL);
         }
 
@@ -1434,6 +1450,20 @@ static void virt_set_secure(Object *obj, bool value, Error **errp)
     vms->secure = value;
 }
 
+static bool virt_get_virt(Object *obj, Error **errp)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+
+    return vms->virt;
+}
+
+static void virt_set_virt(Object *obj, bool value, Error **errp)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+
+    vms->virt = value;
+}
+
 static bool virt_get_highmem(Object *obj, Error **errp)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -1521,6 +1551,16 @@ static void virt_2_9_instance_init(Object *obj)
                                     "Security Extensions (TrustZone)",
                                     NULL);
 
+    /* EL2 is also disabled by default, for similar reasons */
+    vms->virt = false;
+    object_property_add_bool(obj, "virtualization", virt_get_virt,
+                             virt_set_virt, NULL);
+    object_property_set_description(obj, "virtualization",
+                                    "Set on/off to enable/disable emulating a "
+                                    "guest CPU which implements the ARM "
+                                    "Virtualization Extensions",
+                                    NULL);
+
     /* High memory is enabled by default */
     vms->highmem = true;
     object_property_add_bool(obj, "highmem", virt_get_highmem,
-- 
2.7.4

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

* Re: [Qemu-devel] [PULL 26/36] hw/intc/arm_gicv3: Add accessors for ICH_ system registers
  2017-01-19 14:09 ` [Qemu-devel] [PULL 26/36] hw/intc/arm_gicv3: Add accessors for ICH_ system registers Peter Maydell
@ 2017-01-26  9:35   ` Paolo Bonzini
  2017-01-26  9:42     ` Thomas Huth
  0 siblings, 1 reply; 51+ messages in thread
From: Paolo Bonzini @ 2017-01-26  9:35 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel



On 19/01/2017 15:09, Peter Maydell wrote:
> +        uint64_t lr = cs->ich_lr_el2[i];
> +
> +        if ((lr & ICH_LR_EL2_STATE_MASK) == 0 &&
> +            ((lr & ICH_LR_EL2_HW) == 1 || (lr & ICH_LR_EL2_EOI) == 0)) {

This should be "!= 0", not == 1 (reported by Coverity).

Paolo

> +            value |= (1 << i);
> +        }

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

* Re: [Qemu-devel] [PULL 26/36] hw/intc/arm_gicv3: Add accessors for ICH_ system registers
  2017-01-26  9:35   ` Paolo Bonzini
@ 2017-01-26  9:42     ` Thomas Huth
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Huth @ 2017-01-26  9:42 UTC (permalink / raw)
  To: Paolo Bonzini, Peter Maydell, qemu-devel

On 26.01.2017 10:35, Paolo Bonzini wrote:
> 
> 
> On 19/01/2017 15:09, Peter Maydell wrote:
>> +        uint64_t lr = cs->ich_lr_el2[i];
>> +
>> +        if ((lr & ICH_LR_EL2_STATE_MASK) == 0 &&
>> +            ((lr & ICH_LR_EL2_HW) == 1 || (lr & ICH_LR_EL2_EOI) == 0)) {
> 
> This should be "!= 0", not == 1 (reported by Coverity).

A patch for this issue is already on the mailing list - see "arm_gicv3:
Fix broken logic in ELRSR calculation"

 Thomas

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

* Re: [Qemu-devel] [PULL 00/36] target-arm queue
  2017-09-04 14:39 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
@ 2017-09-04 16:20 ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-09-04 16:20 UTC (permalink / raw)
  To: QEMU Developers

On 4 September 2017 at 15:39, Peter Maydell <peter.maydell@linaro.org> wrote:
> Try #2, with the compile failure in kvm32.c fixed
> (trivial change, not resending patches)

Rats, this doesn't work either -- turns out that
boards.h: Define new flag ignore_memory_transaction_failures
breaks the usermode emulators.

I'm going to drop:

>       boards.h: Define new flag ignore_memory_transaction_failures
>       hw/arm: Set ignore_memory_transaction_failures for most ARM boards
>       target/arm: Implement new do_transaction_failed hook

and resend the pullreq.

thanks
-- PMM

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

* [Qemu-devel] [PULL 00/36] target-arm queue
@ 2017-09-04 14:39 Peter Maydell
  2017-09-04 16:20 ` Peter Maydell
  0 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2017-09-04 14:39 UTC (permalink / raw)
  To: qemu-devel

Try #2, with the compile failure in kvm32.c fixed
(trivial change, not resending patches)

thanks
-- PMM

The following changes since commit 98bfaac788be0ca63d7d010c8d4ba100ff1d8278:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2017-09-01-v3' into staging (2017-09-04 13:28:09 +0100)

are available in the git repository at:

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

for you to fetch changes up to 0b8095ec9e924dc00636ab2069d88dec6592a75d:

  arm_gicv3_kvm: Fix compile warning (2017-09-04 15:21:56 +0100)

----------------------------------------------------------------
target-arm:
 * collection of M profile cleanups and minor bugfixes
 * loader: handle ELF files with overlapping zero-init data
 * virt: allow PMU instantiation with userspace irqchip
 * wdt_aspeed: Add support for the reset width register
 * cpu: Define new cpu_transaction_failed() hook
 * arm: Support generating CPU exceptions on memory
   transaction failures (bus faults)
 * Mark some SoC devices as not user-creatable
 * arm: Fix aa64 ldp register writeback
 * arm_gicv3_kvm: Fix compile warning

----------------------------------------------------------------
Andrew Jeffery (2):
      watchdog: wdt_aspeed: Add support for the reset width register
      aspeed_soc: Propagate silicon-rev to watchdog

Andrew Jones (4):
      hw/arm/virt: add pmu interrupt state
      target/arm/kvm: pmu: split init and set-irq stages
      hw/arm/virt: allow pmu instantiation with userspace irqchip
      target/arm/kvm: pmu: improve error handling

Peter Maydell (25):
      target/arm: Use MMUAccessType enum rather than int
      target/arm: Don't trap WFI/WFE for M profile
      target/arm: Consolidate PMSA handling in get_phys_addr()
      target/arm: Tighten up Thumb decode where new v8M insns will be
      hw/intc/armv7m_nvic.c: Remove out of date comment
      target/arm: Remove incorrect comment about MPU_CTRL
      target/arm: Fix outdated comment about exception exit
      target/arm: Define and use XPSR bit masks
      target/arm: Don't store M profile PRIMASK and FAULTMASK in daif
      target/arm: Don't use cpsr_write/cpsr_read to transfer M profile XPSR
      target/arm: Make arm_cpu_dump_state() handle the M-profile XPSR
      target/arm: Don't calculate lr in arm_v7m_cpu_do_interrupt() until needed
      target/arm: Create and use new function arm_v7m_is_handler_mode()
      armv7m_nvic.h: Move from include/hw/arm to include/hw/intc
      nvic: Implement "user accesses BusFault" SCS region behaviour
      loader: Handle ELF files with overlapping zero-initialized data
      loader: Ignore zero-sized ELF segments
      memory.h: Move MemTxResult type to memattrs.h
      cpu: Define new cpu_transaction_failed() hook
      cputlb: Support generating CPU exceptions on memory transaction failures
      boards.h: Define new flag ignore_memory_transaction_failures
      hw/arm: Set ignore_memory_transaction_failures for most ARM boards
      target/arm: Factor out fault delivery code
      target/arm: Allow deliver_fault() caller to specify EA bit
      target/arm: Implement new do_transaction_failed hook

Philippe Mathieu-Daudé (1):
      hw/arm: use defined type name instead of hard-coded string

Pranith Kumar (1):
      arm_gicv3_kvm: Fix compile warning

Richard Henderson (1):
      target/arm: Fix aa64 ldp register writeback

Thomas Huth (2):
      hw/arm/aspeed_soc: Mark devices as user_creatable = false
      hw/arm/digic: Mark device with user_creatable = false

 include/exec/memattrs.h                |  10 +++
 include/exec/memory.h                  |  10 ---
 include/hw/arm/armv7m.h                |   2 +-
 include/hw/boards.h                    |  11 +++
 include/hw/elf_ops.h                   |  72 +++++++++++++--
 include/hw/{arm => intc}/armv7m_nvic.h |   0
 include/hw/watchdog/wdt_aspeed.h       |   2 +
 include/qom/cpu.h                      |  27 ++++++
 softmmu_template.h                     |   4 +-
 target/arm/cpu.h                       |  56 +++++++++---
 target/arm/internals.h                 |  15 +++-
 target/arm/kvm_arm.h                   |   9 +-
 accel/tcg/cputlb.c                     |  32 ++++++-
 hw/arm/armv7m.c                        |   4 +-
 hw/arm/aspeed.c                        |   3 +
 hw/arm/aspeed_soc.c                    |   4 +
 hw/arm/collie.c                        |   1 +
 hw/arm/cubieboard.c                    |   1 +
 hw/arm/digic.c                         |   2 +
 hw/arm/digic_boards.c                  |   1 +
 hw/arm/exynos4210.c                    |   4 +-
 hw/arm/exynos4_boards.c                |   2 +
 hw/arm/gumstix.c                       |   2 +
 hw/arm/highbank.c                      |  13 ++-
 hw/arm/imx25_pdk.c                     |   1 +
 hw/arm/integratorcp.c                  |   1 +
 hw/arm/kzm.c                           |   1 +
 hw/arm/mainstone.c                     |   1 +
 hw/arm/musicpal.c                      |   1 +
 hw/arm/netduino2.c                     |   1 +
 hw/arm/nseries.c                       |   2 +
 hw/arm/omap_sx1.c                      |   2 +
 hw/arm/palm.c                          |   1 +
 hw/arm/raspi.c                         |   1 +
 hw/arm/realview.c                      |  10 ++-
 hw/arm/sabrelite.c                     |   1 +
 hw/arm/spitz.c                         |   4 +
 hw/arm/stellaris.c                     |   2 +
 hw/arm/tosa.c                          |   1 +
 hw/arm/versatilepb.c                   |   2 +
 hw/arm/vexpress.c                      |   7 +-
 hw/arm/virt.c                          |  12 ++-
 hw/arm/xilinx_zynq.c                   |  15 ++--
 hw/arm/xlnx-ep108.c                    |   2 +
 hw/arm/z2.c                            |   1 +
 hw/intc/arm_gicv3_kvm.c                |   2 +-
 hw/intc/armv7m_nvic.c                  |  68 +++++++++-----
 hw/watchdog/wdt_aspeed.c               |  93 ++++++++++++++++---
 qom/cpu.c                              |   7 ++
 target/arm/cpu.c                       |   8 +-
 target/arm/helper.c                    | 124 ++++++++++++-------------
 target/arm/kvm.c                       |   6 +-
 target/arm/kvm32.c                     |   8 +-
 target/arm/kvm64.c                     |  63 +++++++------
 target/arm/machine.c                   |  54 ++++++++++-
 target/arm/op_helper.c                 | 160 ++++++++++++++++++++++-----------
 target/arm/translate-a64.c             |  29 +++---
 target/arm/translate.c                 | 106 ++++++++++++++++------
 58 files changed, 795 insertions(+), 289 deletions(-)
 rename include/hw/{arm => intc}/armv7m_nvic.h (100%)

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

* [Qemu-devel] [PULL 00/36] target-arm queue
@ 2017-09-04 12:25 Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2017-09-04 12:25 UTC (permalink / raw)
  To: qemu-devel

First arm pullreq of the 2.11 cycle. I know I still have some
more stuff on my queue to review, but 36 patches is big enough
as it is; I expect I'll do another pull later this week.

thanks
-- PMM

The following changes since commit 32f0f68bb77289b75a82925f712bb52e16eac3ba:

  Merge remote-tracking branch 'remotes/ehabkost/tags/x86-and-machine-pull-request' into staging (2017-09-01 17:28:54 +0100)

are available in the git repository at:

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

for you to fetch changes up to 1e35c4ce33a94cf78dbf639695cb877ef35920b0:

  arm_gicv3_kvm: Fix compile warning (2017-09-04 12:09:32 +0100)

----------------------------------------------------------------
target-arm:
 * collection of M profile cleanups and minor bugfixes
 * loader: handle ELF files with overlapping zero-init data
 * virt: allow PMU instantiation with userspace irqchip
 * wdt_aspeed: Add support for the reset width register
 * cpu: Define new cpu_transaction_failed() hook
 * arm: Support generating CPU exceptions on memory
   transaction failures (bus faults)
 * Mark some SoC devices as not user-creatable
 * arm: Fix aa64 ldp register writeback
 * arm_gicv3_kvm: Fix compile warning

----------------------------------------------------------------
Andrew Jeffery (2):
      watchdog: wdt_aspeed: Add support for the reset width register
      aspeed_soc: Propagate silicon-rev to watchdog

Andrew Jones (4):
      hw/arm/virt: add pmu interrupt state
      target/arm/kvm: pmu: split init and set-irq stages
      hw/arm/virt: allow pmu instantiation with userspace irqchip
      target/arm/kvm: pmu: improve error handling

Peter Maydell (25):
      target/arm: Use MMUAccessType enum rather than int
      target/arm: Don't trap WFI/WFE for M profile
      target/arm: Consolidate PMSA handling in get_phys_addr()
      target/arm: Tighten up Thumb decode where new v8M insns will be
      hw/intc/armv7m_nvic.c: Remove out of date comment
      target/arm: Remove incorrect comment about MPU_CTRL
      target/arm: Fix outdated comment about exception exit
      target/arm: Define and use XPSR bit masks
      target/arm: Don't store M profile PRIMASK and FAULTMASK in daif
      target/arm: Don't use cpsr_write/cpsr_read to transfer M profile XPSR
      target/arm: Make arm_cpu_dump_state() handle the M-profile XPSR
      target/arm: Don't calculate lr in arm_v7m_cpu_do_interrupt() until needed
      target/arm: Create and use new function arm_v7m_is_handler_mode()
      armv7m_nvic.h: Move from include/hw/arm to include/hw/intc
      nvic: Implement "user accesses BusFault" SCS region behaviour
      loader: Handle ELF files with overlapping zero-initialized data
      loader: Ignore zero-sized ELF segments
      memory.h: Move MemTxResult type to memattrs.h
      cpu: Define new cpu_transaction_failed() hook
      cputlb: Support generating CPU exceptions on memory transaction failures
      boards.h: Define new flag ignore_memory_transaction_failures
      hw/arm: Set ignore_memory_transaction_failures for most ARM boards
      target/arm: Factor out fault delivery code
      target/arm: Allow deliver_fault() caller to specify EA bit
      target/arm: Implement new do_transaction_failed hook

Philippe Mathieu-Daudé (1):
      hw/arm: use defined type name instead of hard-coded string

Pranith Kumar (1):
      arm_gicv3_kvm: Fix compile warning

Richard Henderson (1):
      target/arm: Fix aa64 ldp register writeback

Thomas Huth (2):
      hw/arm/aspeed_soc: Mark devices as user_creatable = false
      hw/arm/digic: Mark device with user_creatable = false

 include/exec/memattrs.h                |  10 +++
 include/exec/memory.h                  |  10 ---
 include/hw/arm/armv7m.h                |   2 +-
 include/hw/boards.h                    |  11 +++
 include/hw/elf_ops.h                   |  72 +++++++++++++--
 include/hw/{arm => intc}/armv7m_nvic.h |   0
 include/hw/watchdog/wdt_aspeed.h       |   2 +
 include/qom/cpu.h                      |  27 ++++++
 softmmu_template.h                     |   4 +-
 target/arm/cpu.h                       |  56 +++++++++---
 target/arm/internals.h                 |  15 +++-
 target/arm/kvm_arm.h                   |   9 +-
 accel/tcg/cputlb.c                     |  32 ++++++-
 hw/arm/armv7m.c                        |   4 +-
 hw/arm/aspeed.c                        |   3 +
 hw/arm/aspeed_soc.c                    |   4 +
 hw/arm/collie.c                        |   1 +
 hw/arm/cubieboard.c                    |   1 +
 hw/arm/digic.c                         |   2 +
 hw/arm/digic_boards.c                  |   1 +
 hw/arm/exynos4210.c                    |   4 +-
 hw/arm/exynos4_boards.c                |   2 +
 hw/arm/gumstix.c                       |   2 +
 hw/arm/highbank.c                      |  13 ++-
 hw/arm/imx25_pdk.c                     |   1 +
 hw/arm/integratorcp.c                  |   1 +
 hw/arm/kzm.c                           |   1 +
 hw/arm/mainstone.c                     |   1 +
 hw/arm/musicpal.c                      |   1 +
 hw/arm/netduino2.c                     |   1 +
 hw/arm/nseries.c                       |   2 +
 hw/arm/omap_sx1.c                      |   2 +
 hw/arm/palm.c                          |   1 +
 hw/arm/raspi.c                         |   1 +
 hw/arm/realview.c                      |  10 ++-
 hw/arm/sabrelite.c                     |   1 +
 hw/arm/spitz.c                         |   4 +
 hw/arm/stellaris.c                     |   2 +
 hw/arm/tosa.c                          |   1 +
 hw/arm/versatilepb.c                   |   2 +
 hw/arm/vexpress.c                      |   7 +-
 hw/arm/virt.c                          |  12 ++-
 hw/arm/xilinx_zynq.c                   |  15 ++--
 hw/arm/xlnx-ep108.c                    |   2 +
 hw/arm/z2.c                            |   1 +
 hw/intc/arm_gicv3_kvm.c                |   2 +-
 hw/intc/armv7m_nvic.c                  |  68 +++++++++-----
 hw/watchdog/wdt_aspeed.c               |  93 ++++++++++++++++---
 qom/cpu.c                              |   7 ++
 target/arm/cpu.c                       |   8 +-
 target/arm/helper.c                    | 124 ++++++++++++-------------
 target/arm/kvm.c                       |   6 +-
 target/arm/kvm32.c                     |   7 +-
 target/arm/kvm64.c                     |  63 +++++++------
 target/arm/machine.c                   |  54 ++++++++++-
 target/arm/op_helper.c                 | 160 ++++++++++++++++++++++-----------
 target/arm/translate-a64.c             |  29 +++---
 target/arm/translate.c                 | 106 ++++++++++++++++------
 58 files changed, 795 insertions(+), 288 deletions(-)
 rename include/hw/{arm => intc}/armv7m_nvic.h (100%)

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

* Re: [Qemu-devel] [PULL 00/36] target-arm queue
  2016-09-22 17:21 Peter Maydell
  2016-09-22 19:58 ` no-reply
@ 2016-09-23  9:57 ` Peter Maydell
  1 sibling, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2016-09-23  9:57 UTC (permalink / raw)
  To: QEMU Developers

On 22 September 2016 at 18:21, Peter Maydell <peter.maydell@linaro.org> wrote:
> ARM queue; my to-review pile is not yet empty but since
> I have a conference next week I wanted to get the stuff
> I had managed to review out.
>
> thanks
> -- PMM
>
> The following changes since commit 430da7a81d356e368ccd88dcca60f38da9aa5b9a:
>
>   Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20160915' into staging (2016-09-22 15:39:54 +0100)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20160922
>
> for you to fetch changes up to d675765a0244af1d65c292f2508009f1bd13e1b6:
>
>   imx: Use 'const char', not 'char const' (2016-09-22 18:13:09 +0100)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * add Cortex-A7 CPU
>  * new ast2500 SoC model and evaluation board
>  * palmetto-bmc: remove stray double assignment
>  * aspeed: clean up RAM size handling
>  * ptimer: framework for defining policy bits to change
>    behaviour choices for different timer devices
>  * ptimer: add some test cases
>  * cadence_gem: add queue support
>  * loader: support loading images to specified address spaces
>  * loader: support auto-detect of ELF architecture from file
>  * dma: xlnx-zynq-devcfg: Fix up XLNX_ZYNQ_DEVCFG_R_MAX
>  * vmstateify ssd0323
>  * vmstateify ssi-sd
>  * disas/arm.c: remove unused macros
>  * imx: use 'const char', not 'char const'

Applied, thanks.

-- PMM

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

* Re: [Qemu-devel] [PULL 00/36] target-arm queue
  2016-09-22 17:21 Peter Maydell
@ 2016-09-22 19:58 ` no-reply
  2016-09-23  9:57 ` Peter Maydell
  1 sibling, 0 replies; 51+ messages in thread
From: no-reply @ 2016-09-22 19:58 UTC (permalink / raw)
  To: peter.maydell; +Cc: famz, qemu-devel

Hi,

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

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

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

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

# Useful git options
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 show --no-patch --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/1474564935-23831-1-git-send-email-peter.maydell@linaro.org -> patchew/1474564935-23831-1-git-send-email-peter.maydell@linaro.org
Switched to a new branch 'test'
5968e02 imx: Use 'const char', not 'char const'
1fb0cf3 disas/arm.c: Remove unused macro definitions
f347c98 vmstateify ssi-sd
9f4c6c7 vmstateify ssd0323 display
0e81a82 dma: xlnx-zynq-devcfg: Fix up XLNX_ZYNQ_DEVCFG_R_MAX
a40249e loader: Add AddressSpace loading support to targphys
bd6b978 loader: Add AddressSpace loading support to uImages
79a76bc loader: Add AddressSpace loading support to ELFs
7732745 loader: Allow a custom AddressSpace when loading ROMs
a8295d6 loader: Use the specified MemoryRegion
b9f8718 loader: Allow ELF loader to auto-detect the ELF arch
730e6a6 xlnx-zynqmp: Set the number of priority queues
7c1190d cadence_gem: Correct indentation
f43c4cb cadence_gem: Add queue support
99929ad cadence_gem: Add support for screening
f89652a cadence_gem: Add the num-priority-queues property
19770cb cadence_gem: QOMify Cadence GEM
abb1719 tests: Add ptimer tests
bc870db hw/ptimer: Suppress error messages under qtest
92bbf61 hw/ptimer: Introduce timer policy feature
91bd052 hw/ptimer: Actually stop the timer in case of error
9b990c0 aspeed: allocate RAM after the memory controller has checked the size
f20b9d3 aspeed: add a ram_size property to the memory controller
d8437c9 aspeed: use error_report instead of LOG_GUEST_ERROR
7707c96 aspeed: calculate the RAM size bits at realize time
83c7ed2 palmetto-bmc: remove extra no_sdcard assignement
bfd6c40 arm: add support for an ast2500 evaluation board
1d6d8ff aspeed: add a ast2500 SoC and support to the SCU and SDMC controllers
72d67aa hw/misc: use macros to define hw-strap1 register on the AST2400 Aspeed SoC
74a36a5 palmetto-bmc: add board specific configuration
786f13c palmetto-bmc: replace palmetto_bmc with aspeed
7dfef30 palmetto-bmc: rename the Aspeed board file to aspeed.c
00956c8 aspeed-soc: provide a framework to add new SoCs
aeb8aac ast2400: replace ast2400 with aspeed_soc
910bc01 ast2400: rename the Aspeed SoC files to aspeed_soc
6ad8241 arm: add Cortex A7 CPU parameters

=== OUTPUT BEGIN ===
Checking PATCH 1/36: arm: add Cortex A7 CPU parameters...
Checking PATCH 2/36: ast2400: rename the Aspeed SoC files to aspeed_soc...
Checking PATCH 3/36: ast2400: replace ast2400 with aspeed_soc...
Checking PATCH 4/36: aspeed-soc: provide a framework to add new SoCs...
Checking PATCH 5/36: palmetto-bmc: rename the Aspeed board file to aspeed.c...
Checking PATCH 6/36: palmetto-bmc: replace palmetto_bmc with aspeed...
Checking PATCH 7/36: palmetto-bmc: add board specific configuration...
Checking PATCH 8/36: hw/misc: use macros to define hw-strap1 register on the AST2400 Aspeed SoC...
Checking PATCH 9/36: aspeed: add a ast2500 SoC and support to the SCU and SDMC controllers...
Checking PATCH 10/36: arm: add support for an ast2500 evaluation board...
Checking PATCH 11/36: palmetto-bmc: remove extra no_sdcard assignement...
Checking PATCH 12/36: aspeed: calculate the RAM size bits at realize time...
Checking PATCH 13/36: aspeed: use error_report instead of LOG_GUEST_ERROR...
Checking PATCH 14/36: aspeed: add a ram_size property to the memory controller...
Checking PATCH 15/36: aspeed: allocate RAM after the memory controller has checked the size...
Checking PATCH 16/36: hw/ptimer: Actually stop the timer in case of error...
Checking PATCH 17/36: hw/ptimer: Introduce timer policy feature...
Checking PATCH 18/36: hw/ptimer: Suppress error messages under qtest...
Checking PATCH 19/36: tests: Add ptimer tests...
WARNING: line over 80 characters
#694: FILE: tests/ptimer-test.c:525:
+        g_strdup_printf("/ptimer/on_the_fly_mode_change policy=%s", policy_name),

WARNING: line over 80 characters
#698: FILE: tests/ptimer-test.c:529:
+        g_strdup_printf("/ptimer/on_the_fly_period_change policy=%s", policy_name),

WARNING: line over 80 characters
#702: FILE: tests/ptimer-test.c:533:
+        g_strdup_printf("/ptimer/on_the_fly_freq_change policy=%s", policy_name),

total: 0 errors, 3 warnings, 722 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 20/36: cadence_gem: QOMify Cadence GEM...
Checking PATCH 21/36: cadence_gem: Add the num-priority-queues property...
Checking PATCH 22/36: cadence_gem: Add support for screening...
Checking PATCH 23/36: cadence_gem: Add queue support...
ERROR: suspect code indent for conditional statements (4, 4)
#154: FILE: hw/net/cadence_gem.c:1056:
+    for (q = s->num_priority_queues - 1; q >= 0; q--) {
     /* read current descriptor */

total: 1 errors, 0 warnings, 285 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 24/36: cadence_gem: Correct indentation...
Checking PATCH 25/36: xlnx-zynqmp: Set the number of priority queues...
Checking PATCH 26/36: loader: Allow ELF loader to auto-detect the ELF arch...
Checking PATCH 27/36: loader: Use the specified MemoryRegion...
Checking PATCH 28/36: loader: Allow a custom AddressSpace when loading ROMs...
Checking PATCH 29/36: loader: Add AddressSpace loading support to ELFs...
Checking PATCH 30/36: loader: Add AddressSpace loading support to uImages...
Checking PATCH 31/36: loader: Add AddressSpace loading support to targphys...
Checking PATCH 32/36: dma: xlnx-zynq-devcfg: Fix up XLNX_ZYNQ_DEVCFG_R_MAX...
Checking PATCH 33/36: vmstateify ssd0323 display...
Checking PATCH 34/36: vmstateify ssi-sd...
Checking PATCH 35/36: disas/arm.c: Remove unused macro definitions...
Checking PATCH 36/36: imx: Use 'const char', not 'char const'...
=== 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] 51+ messages in thread

* [Qemu-devel] [PULL 00/36] target-arm queue
@ 2016-09-22 17:21 Peter Maydell
  2016-09-22 19:58 ` no-reply
  2016-09-23  9:57 ` Peter Maydell
  0 siblings, 2 replies; 51+ messages in thread
From: Peter Maydell @ 2016-09-22 17:21 UTC (permalink / raw)
  To: qemu-devel

ARM queue; my to-review pile is not yet empty but since
I have a conference next week I wanted to get the stuff
I had managed to review out.

thanks
-- PMM

The following changes since commit 430da7a81d356e368ccd88dcca60f38da9aa5b9a:

  Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20160915' into staging (2016-09-22 15:39:54 +0100)

are available in the git repository at:

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

for you to fetch changes up to d675765a0244af1d65c292f2508009f1bd13e1b6:

  imx: Use 'const char', not 'char const' (2016-09-22 18:13:09 +0100)

----------------------------------------------------------------
target-arm queue:
 * add Cortex-A7 CPU
 * new ast2500 SoC model and evaluation board
 * palmetto-bmc: remove stray double assignment
 * aspeed: clean up RAM size handling
 * ptimer: framework for defining policy bits to change
   behaviour choices for different timer devices
 * ptimer: add some test cases
 * cadence_gem: add queue support
 * loader: support loading images to specified address spaces
 * loader: support auto-detect of ELF architecture from file
 * dma: xlnx-zynq-devcfg: Fix up XLNX_ZYNQ_DEVCFG_R_MAX
 * vmstateify ssd0323
 * vmstateify ssi-sd
 * disas/arm.c: remove unused macros
 * imx: use 'const char', not 'char const'

----------------------------------------------------------------
Alistair Francis (12):
      cadence_gem: QOMify Cadence GEM
      cadence_gem: Add the num-priority-queues property
      cadence_gem: Add support for screening
      cadence_gem: Add queue support
      cadence_gem: Correct indentation
      xlnx-zynqmp: Set the number of priority queues
      loader: Allow ELF loader to auto-detect the ELF arch
      loader: Use the specified MemoryRegion
      loader: Allow a custom AddressSpace when loading ROMs
      loader: Add AddressSpace loading support to ELFs
      loader: Add AddressSpace loading support to uImages
      loader: Add AddressSpace loading support to targphys

Andrey Yurovsky (1):
      arm: add Cortex A7 CPU parameters

Cédric Le Goater (14):
      ast2400: rename the Aspeed SoC files to aspeed_soc
      ast2400: replace ast2400 with aspeed_soc
      aspeed-soc: provide a framework to add new SoCs
      palmetto-bmc: rename the Aspeed board file to aspeed.c
      palmetto-bmc: replace palmetto_bmc with aspeed
      palmetto-bmc: add board specific configuration
      hw/misc: use macros to define hw-strap1 register on the AST2400 Aspeed SoC
      aspeed: add a ast2500 SoC and support to the SCU and SDMC controllers
      arm: add support for an ast2500 evaluation board
      palmetto-bmc: remove extra no_sdcard assignement
      aspeed: calculate the RAM size bits at realize time
      aspeed: use error_report instead of LOG_GUEST_ERROR
      aspeed: add a ram_size property to the memory controller
      aspeed: allocate RAM after the memory controller has checked the size

Dmitry Osipenko (4):
      hw/ptimer: Actually stop the timer in case of error
      hw/ptimer: Introduce timer policy feature
      hw/ptimer: Suppress error messages under qtest
      tests: Add ptimer tests

Dr. David Alan Gilbert (2):
      vmstateify ssd0323 display
      vmstateify ssi-sd

Nathan Rossi (1):
      dma: xlnx-zynq-devcfg: Fix up XLNX_ZYNQ_DEVCFG_R_MAX

Peter Maydell (2):
      disas/arm.c: Remove unused macro definitions
      imx: Use 'const char', not 'char const'

 disas/arm.c                        |  11 -
 hw/arm/Makefile.objs               |   2 +-
 hw/arm/aspeed.c                    | 197 +++++++++++++
 hw/arm/{ast2400.c => aspeed_soc.c} | 131 +++++----
 hw/arm/musicpal.c                  |   2 +-
 hw/arm/palmetto-bmc.c              | 102 -------
 hw/arm/xlnx-zynqmp.c               |   2 +
 hw/core/loader.c                   |  89 ++++--
 hw/core/ptimer.c                   |  14 +-
 hw/display/ssd0323.c               | 102 +++----
 hw/dma/xilinx_axidma.c             |   2 +-
 hw/m68k/mcf5206.c                  |   2 +-
 hw/m68k/mcf5208.c                  |   2 +-
 hw/misc/aspeed_scu.c               |  45 ++-
 hw/misc/aspeed_sdmc.c              |  45 ++-
 hw/misc/imx25_ccm.c                |   2 +-
 hw/misc/imx31_ccm.c                |   2 +-
 hw/misc/imx6_ccm.c                 |   4 +-
 hw/misc/imx6_src.c                 |   2 +-
 hw/net/cadence_gem.c               | 571 +++++++++++++++++++++++++++----------
 hw/net/fsl_etsec/etsec.c           |   2 +-
 hw/net/lan9118.c                   |   2 +-
 hw/sd/ssi-sd.c                     |  70 ++---
 hw/ssi/imx_spi.c                   |   2 +-
 hw/timer/allwinner-a10-pit.c       |   2 +-
 hw/timer/arm_timer.c               |   2 +-
 hw/timer/digic-timer.c             |   2 +-
 hw/timer/etraxfs_timer.c           |   6 +-
 hw/timer/exynos4210_mct.c          |   7 +-
 hw/timer/exynos4210_pwm.c          |   2 +-
 hw/timer/exynos4210_rtc.c          |   4 +-
 hw/timer/grlib_gptimer.c           |   2 +-
 hw/timer/imx_epit.c                |   6 +-
 hw/timer/imx_gpt.c                 |   4 +-
 hw/timer/lm32_timer.c              |   2 +-
 hw/timer/milkymist-sysctl.c        |   4 +-
 hw/timer/puv3_ost.c                |   2 +-
 hw/timer/sh_timer.c                |   2 +-
 hw/timer/slavio_timer.c            |   2 +-
 hw/timer/xilinx_timer.c            |   2 +-
 include/hw/arm/aspeed_soc.h        |  59 ++++
 include/hw/arm/ast2400.h           |  44 ---
 include/hw/dma/xlnx-zynq-devcfg.h  |   2 +-
 include/hw/elf_ops.h               |  10 +-
 include/hw/loader.h                |  73 ++++-
 include/hw/misc/aspeed_scu.h       | 193 +++++++++++++
 include/hw/misc/aspeed_sdmc.h      |   2 +
 include/hw/net/cadence_gem.h       |  19 +-
 include/hw/ptimer.h                |  25 +-
 stubs/vmstate.c                    |   5 +
 target-arm/cpu.c                   |  46 +++
 tests/Makefile.include             |   2 +
 tests/ptimer-test-stubs.c          | 107 +++++++
 tests/ptimer-test.c                | 568 ++++++++++++++++++++++++++++++++++++
 tests/ptimer-test.h                |  22 ++
 55 files changed, 2084 insertions(+), 549 deletions(-)
 create mode 100644 hw/arm/aspeed.c
 rename hw/arm/{ast2400.c => aspeed_soc.c} (59%)
 delete mode 100644 hw/arm/palmetto-bmc.c
 create mode 100644 include/hw/arm/aspeed_soc.h
 delete mode 100644 include/hw/arm/ast2400.h
 create mode 100644 tests/ptimer-test-stubs.c
 create mode 100644 tests/ptimer-test.c
 create mode 100644 tests/ptimer-test.h

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

* Re: [Qemu-devel] [PULL 00/36] target-arm queue
  2016-02-18 15:20 Peter Maydell
@ 2016-02-18 15:50 ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2016-02-18 15:50 UTC (permalink / raw)
  To: QEMU Developers

On 18 February 2016 at 15:20, Peter Maydell <peter.maydell@linaro.org> wrote:
> Second try, with the typedef issue fixed.
>
> -- PMM
>
>
> The following changes since commit 339b665c883b209982fa161dc090ffaf242ab12b:
>
>   Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.6-20160218' into staging (2016-02-18 10:29:47 +0000)
>
> are available in the git repository at:
>
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20160218-1
>
> for you to fetch changes up to 5d83e348e7f6499f27b6431b0d91af8dcfb06763:
>
>   hw/timer: QOM'ify pxa2xx_timer (2016-02-18 14:50:51 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * implement or fix various EL3 trap behaviour for system registers
>  * clean up the trap/undef handling of the SRS instruction
>  * add some missing AArch64 performance monitor system registers
>  * implement reset for the PL061 GPIO device
>  * QOMify sd.c and the pxa2xx_mmci device
>  * SD card emulation fixes for booting Tianocore UEFI on RPi2
>  * QOMify various ARM timer devices

Applied, thanks.

-- PMM

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

* [Qemu-devel] [PULL 00/36] target-arm queue
@ 2016-02-18 15:20 Peter Maydell
  2016-02-18 15:50 ` Peter Maydell
  0 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2016-02-18 15:20 UTC (permalink / raw)
  To: qemu-devel

Second try, with the typedef issue fixed.

-- PMM


The following changes since commit 339b665c883b209982fa161dc090ffaf242ab12b:

  Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.6-20160218' into staging (2016-02-18 10:29:47 +0000)

are available in the git repository at:


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

for you to fetch changes up to 5d83e348e7f6499f27b6431b0d91af8dcfb06763:

  hw/timer: QOM'ify pxa2xx_timer (2016-02-18 14:50:51 +0000)

----------------------------------------------------------------
target-arm queue:
 * implement or fix various EL3 trap behaviour for system registers
 * clean up the trap/undef handling of the SRS instruction
 * add some missing AArch64 performance monitor system registers
 * implement reset for the PL061 GPIO device
 * QOMify sd.c and the pxa2xx_mmci device
 * SD card emulation fixes for booting Tianocore UEFI on RPi2
 * QOMify various ARM timer devices

----------------------------------------------------------------
Alistair Francis (3):
      target-arm: Add the pmceid0 and pmceid1 registers
      target-arm: Add the pmovsclr_el0 and pmintenclr_el1 registers
      target-arm: Add PMUSERENR_EL0 register

Andrew Baumann (3):
      hw/sd: implement CMD23 (SET_BLOCK_COUNT) for MMC compatibility
      hw/sd: model a power-up delay, as a workaround for an EDK2 bug
      hw/sd: use guest error logging rather than fprintf to stderr

Peter Maydell (21):
      target-arm: correct CNTFRQ access rights
      target-arm: Fix handling of SCR.SMD
      target-arm: Implement MDCR_EL3.TDOSA and MDCR_EL2.TDOSA traps
      target-arm: Implement MDCR_EL2.TDRA traps
      target-arm: Implement MDCR_EL3.TDA and MDCR_EL2.TDA traps
      target-arm: Report correct syndrome for FPEXC32_EL2 traps
      target-arm: Clean up trap/undef handling of SRS
      target-arm: Move get/set_r13_banked() to op_helper.c
      target-arm: Move bank_number() into internals.h
      target-arm: Combine user-only and softmmu get/set_r13_banked()
      target-arm: UNDEF in the UNPREDICTABLE SRS-from-System case
      hw/sd/sdhci.c: Remove x-drive property
      hw/sd/sd.c: QOMify
      hw/sd/sd.c: Convert sd_reset() function into Device reset method
      hw/sd: Add QOM bus which SD cards plug in to
      hw/sd/sdhci.c: Update to use SDBus APIs
      sdhci_sysbus: Create SD card device in users, not the device itself
      hw/sd/pxa2xx_mmci: convert to SysBusDevice object
      hw/sd/pxa2xx_mmci: Update to use new SDBus APIs
      hw/sd/pxa2xx_mmci: Convert to VMStateDescription
      hw/sd/pxa2xx_mmci: Add reset function

Wei Huang (2):
      ARM: PL061: Clear PL061 device state after reset
      ARM: PL061: Cleaning field of PL061 device state

xiaoqiang.zhao (7):
      hw/timer: QOM'ify arm_timer (pass 1)
      hw/timer: QOM'ify arm_timer (pass 2)
      hw/timer: QOM'ify exynos4210_mct
      hw/timer: QOM'ify exynos4210_pwm
      hw/timer: QOM'ify exynos4210_rtc
      hw/timer: QOM'ify pl031
      hw/timer: QOM'ify pxa2xx_timer

 hw/arm/xilinx_zynq.c      |  17 ++-
 hw/arm/xlnx-ep108.c       |  21 ++++
 hw/arm/xlnx-zynqmp.c      |   8 ++
 hw/gpio/pl061.c           |  37 ++++--
 hw/sd/Makefile.objs       |   2 +-
 hw/sd/core.c              | 146 ++++++++++++++++++++++
 hw/sd/pxa2xx_mmci.c       | 304 ++++++++++++++++++++++++++++++----------------
 hw/sd/sd.c                | 289 ++++++++++++++++++++++++++++++++++++-------
 hw/sd/sdhci.c             |  82 +++++++------
 hw/timer/arm_timer.c      |  42 +++----
 hw/timer/exynos4210_mct.c |  12 +-
 hw/timer/exynos4210_pwm.c |  12 +-
 hw/timer/exynos4210_rtc.c |  12 +-
 hw/timer/pl031.c          |  11 +-
 hw/timer/pxa2xx_timer.c   |  36 +++---
 include/hw/sd/sd.h        |  65 ++++++++++
 include/hw/sd/sdhci.h     |   3 +-
 target-arm/cpu-qom.h      |   2 +
 target-arm/cpu.c          |   2 +
 target-arm/cpu.h          |  29 +++++
 target-arm/cpu64.c        |   2 +
 target-arm/helper.c       | 214 ++++++++++++++++++++------------
 target-arm/internals.h    |  26 +++-
 target-arm/op_helper.c    |  51 +++++++-
 target-arm/translate.c    |  67 +++++++++-
 25 files changed, 1144 insertions(+), 348 deletions(-)
 create mode 100644 hw/sd/core.c

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

* Re: [Qemu-devel] [PULL 00/36] target-arm queue
  2016-02-18 14:34 Peter Maydell
@ 2016-02-18 15:19 ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2016-02-18 15:19 UTC (permalink / raw)
  To: QEMU Developers

On 18 February 2016 at 14:34, Peter Maydell <peter.maydell@linaro.org> wrote:
> ARM pullreq with a whole pile of stuff; QOMification of SD cards
> is perhaps the biggest individual thing here.
>
> thanks
> -- PMM
>
> The following changes since commit 339b665c883b209982fa161dc090ffaf242ab12b:
>
>   Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.6-20160218' into staging (2016-02-18 10:29:47 +0000)
>
> are available in the git repository at:
>
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20160218

Minor fixup needed for the w32 compiler that doesn't like duplicate
typedefs, to the "hw/sd/pxa2xx_mmci: convert to SysBusDevice object"
patch:

diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
index cadbba3..e3753e5 100644
--- a/hw/sd/pxa2xx_mmci.c
+++ b/hw/sd/pxa2xx_mmci.c
@@ -21,7 +21,7 @@
 #define TYPE_PXA2XX_MMCI "pxa2xx-mmci"
 #define PXA2XX_MMCI(obj) OBJECT_CHECK(PXA2xxMMCIState, (obj), TYPE_PXA2XX_MMCI)

-typedef struct PXA2xxMMCIState {
+struct PXA2xxMMCIState {
     SysBusDevice parent_obj;

     MemoryRegion iomem;
@@ -57,7 +57,7 @@ typedef struct PXA2xxMMCIState {
     int resp_len;

     int cmdreq;
-} PXA2xxMMCIState;
+};

 #define MMC_STRPCL     0x00    /* MMC Clock Start/Stop register */
 #define MMC_STAT       0x04    /* MMC Status register */

New cover letter coming up shortly.

-- PMM

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

* [Qemu-devel] [PULL 00/36] target-arm queue
@ 2016-02-18 14:34 Peter Maydell
  2016-02-18 15:19 ` Peter Maydell
  0 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2016-02-18 14:34 UTC (permalink / raw)
  To: qemu-devel

ARM pullreq with a whole pile of stuff; QOMification of SD cards
is perhaps the biggest individual thing here.

thanks
-- PMM

The following changes since commit 339b665c883b209982fa161dc090ffaf242ab12b:

  Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.6-20160218' into staging (2016-02-18 10:29:47 +0000)

are available in the git repository at:


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

for you to fetch changes up to ee24ff5593b6f88c693af1b11e5af095ed7c4696:

  hw/timer: QOM'ify pxa2xx_timer (2016-02-18 14:26:33 +0000)

----------------------------------------------------------------
target-arm queue:
 * implement or fix various EL3 trap behaviour for system registers
 * clean up the trap/undef handling of the SRS instruction
 * add some missing AArch64 performance monitor system registers
 * implement reset for the PL061 GPIO device
 * QOMify sd.c and the pxa2xx_mmci device
 * SD card emulation fixes for booting Tianocore UEFI on RPi2
 * QOMify various ARM timer devices

----------------------------------------------------------------
Alistair Francis (3):
      target-arm: Add the pmceid0 and pmceid1 registers
      target-arm: Add the pmovsclr_el0 and pmintenclr_el1 registers
      target-arm: Add PMUSERENR_EL0 register

Andrew Baumann (3):
      hw/sd: implement CMD23 (SET_BLOCK_COUNT) for MMC compatibility
      hw/sd: model a power-up delay, as a workaround for an EDK2 bug
      hw/sd: use guest error logging rather than fprintf to stderr

Peter Maydell (21):
      target-arm: correct CNTFRQ access rights
      target-arm: Fix handling of SCR.SMD
      target-arm: Implement MDCR_EL3.TDOSA and MDCR_EL2.TDOSA traps
      target-arm: Implement MDCR_EL2.TDRA traps
      target-arm: Implement MDCR_EL3.TDA and MDCR_EL2.TDA traps
      target-arm: Report correct syndrome for FPEXC32_EL2 traps
      target-arm: Clean up trap/undef handling of SRS
      target-arm: Move get/set_r13_banked() to op_helper.c
      target-arm: Move bank_number() into internals.h
      target-arm: Combine user-only and softmmu get/set_r13_banked()
      target-arm: UNDEF in the UNPREDICTABLE SRS-from-System case
      hw/sd/sdhci.c: Remove x-drive property
      hw/sd/sd.c: QOMify
      hw/sd/sd.c: Convert sd_reset() function into Device reset method
      hw/sd: Add QOM bus which SD cards plug in to
      hw/sd/sdhci.c: Update to use SDBus APIs
      sdhci_sysbus: Create SD card device in users, not the device itself
      hw/sd/pxa2xx_mmci: convert to SysBusDevice object
      hw/sd/pxa2xx_mmci: Update to use new SDBus APIs
      hw/sd/pxa2xx_mmci: Convert to VMStateDescription
      hw/sd/pxa2xx_mmci: Add reset function

Wei Huang (2):
      ARM: PL061: Clear PL061 device state after reset
      ARM: PL061: Cleaning field of PL061 device state

xiaoqiang.zhao (7):
      hw/timer: QOM'ify arm_timer (pass 1)
      hw/timer: QOM'ify arm_timer (pass 2)
      hw/timer: QOM'ify exynos4210_mct
      hw/timer: QOM'ify exynos4210_pwm
      hw/timer: QOM'ify exynos4210_rtc
      hw/timer: QOM'ify pl031
      hw/timer: QOM'ify pxa2xx_timer

 hw/arm/xilinx_zynq.c      |  17 ++-
 hw/arm/xlnx-ep108.c       |  21 ++++
 hw/arm/xlnx-zynqmp.c      |   8 ++
 hw/gpio/pl061.c           |  37 ++++--
 hw/sd/Makefile.objs       |   2 +-
 hw/sd/core.c              | 146 ++++++++++++++++++++++
 hw/sd/pxa2xx_mmci.c       | 306 ++++++++++++++++++++++++++++++----------------
 hw/sd/sd.c                | 289 ++++++++++++++++++++++++++++++++++++-------
 hw/sd/sdhci.c             |  82 +++++++------
 hw/timer/arm_timer.c      |  42 +++----
 hw/timer/exynos4210_mct.c |  12 +-
 hw/timer/exynos4210_pwm.c |  12 +-
 hw/timer/exynos4210_rtc.c |  12 +-
 hw/timer/pl031.c          |  11 +-
 hw/timer/pxa2xx_timer.c   |  36 +++---
 include/hw/sd/sd.h        |  65 ++++++++++
 include/hw/sd/sdhci.h     |   3 +-
 target-arm/cpu-qom.h      |   2 +
 target-arm/cpu.c          |   2 +
 target-arm/cpu.h          |  29 +++++
 target-arm/cpu64.c        |   2 +
 target-arm/helper.c       | 214 ++++++++++++++++++++------------
 target-arm/internals.h    |  26 +++-
 target-arm/op_helper.c    |  51 +++++++-
 target-arm/translate.c    |  67 +++++++++-
 25 files changed, 1145 insertions(+), 349 deletions(-)
 create mode 100644 hw/sd/core.c

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

* Re: [Qemu-devel] [PULL 00/36] target-arm queue
  2016-01-21 14:55 Peter Maydell
@ 2016-01-21 15:53 ` Peter Maydell
  0 siblings, 0 replies; 51+ messages in thread
From: Peter Maydell @ 2016-01-21 15:53 UTC (permalink / raw)
  To: QEMU Developers

On 21 January 2016 at 14:55, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> The biggie here is the multi-ases support and corresponding TrustZone
> support code. There are also a bunch of other comparatively minor
> things...
>
> thanks
> -- PMM
>
> The following changes since commit 3c9331c47f22224118d5019b0af8eac704824d8d:
>
>   Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2016-01-21 13:09:47 +0000)
>
> are available in the git repository at:
>
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20160121
>
> for you to fetch changes up to 03fbf20f4da58f41998dc10ec7542f65d37ba759:
>
>   target-arm: Implement FPEXC32_EL2 system register (2016-01-21 14:15:09 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * connect SPI devices in Xilinx Zynq platforms
>  * multiple-address-space support
>  * use multiple-address-space support for ARM TrustZone
>  * arm_gic: return correct ID registers for 11MPCore/v1/v2 GICs
>  * various fixes for (currently disabled) AArch64 EL2 and EL3 support
>  * add 'always-on' property to the virt board timer DT entry
>

Applied, thanks.

-- PMM

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

* [Qemu-devel] [PULL 00/36] target-arm queue
@ 2016-01-21 14:55 Peter Maydell
  2016-01-21 15:53 ` Peter Maydell
  0 siblings, 1 reply; 51+ messages in thread
From: Peter Maydell @ 2016-01-21 14:55 UTC (permalink / raw)
  To: qemu-devel


The biggie here is the multi-ases support and corresponding TrustZone
support code. There are also a bunch of other comparatively minor
things...

thanks
-- PMM

The following changes since commit 3c9331c47f22224118d5019b0af8eac704824d8d:

  Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2016-01-21 13:09:47 +0000)

are available in the git repository at:


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

for you to fetch changes up to 03fbf20f4da58f41998dc10ec7542f65d37ba759:

  target-arm: Implement FPEXC32_EL2 system register (2016-01-21 14:15:09 +0000)

----------------------------------------------------------------
target-arm queue:
 * connect SPI devices in Xilinx Zynq platforms
 * multiple-address-space support
 * use multiple-address-space support for ARM TrustZone
 * arm_gic: return correct ID registers for 11MPCore/v1/v2 GICs
 * various fixes for (currently disabled) AArch64 EL2 and EL3 support
 * add 'always-on' property to the virt board timer DT entry

----------------------------------------------------------------
Alistair Francis (6):
      m25p80.c: Add sst25wf080 SPI flash device
      ssi: Move ssi.h into a separate directory
      xilinx_spips: Separate the state struct into a header
      xlnx-zynqmp: Connect the SPI devices
      xlnx-ep108: Connect the SPI Flash
      arm_gic: Update ID registers based on revision

Christoffer Dall (1):
      hw/arm/virt: Add always-on property to the virt board timer

Peter Crosthwaite (4):
      qdev: get_child_bus(): Use QOM lookup if available
      misc: zynq-xadc: Fix off-by-one
      memory: Add address_space_init_shareable()
      qom/cpu: Add MemoryRegion property

Peter Maydell (25):
      exec.c: Don't set cpu->as until cpu_address_space_init
      exec.c: Allow target CPUs to define multiple AddressSpaces
      exec-all.h: Document tlb_set_page_with_attrs, tlb_set_page
      cpu: Add new get_phys_page_attrs_debug() method
      cpu: Add new asidx_from_attrs() method
      cputlb.c: Use correct address space when looking up MemoryRegionSection
      exec.c: Pass MemTxAttrs to iotlb_to_region so it uses the right AS
      exec.c: Add cpu_get_address_space()
      exec.c: Use cpu_get_phys_page_attrs_debug
      exec.c: Use correct AddressSpace in watch_mem_read and watch_mem_write
      target-arm: Add QOM property for Secure memory region
      target-arm: Implement asidx_from_attrs
      target-arm: Implement cpu_get_phys_page_attrs_debug
      target-arm: Support multiple address spaces in page table walks
      hw/arm/virt: Wire up memory region to CPUs explicitly
      hw/arm/virt: add secure memory region and UART
      target-arm: Properly support EL2 and EL3 in arm_el_is_aa64()
      target-arm: Move aarch64_cpu_do_interrupt() to helper.c
      target-arm: Use a single entry point for AArch64 and AArch32 exceptions
      target-arm: Pull semihosting handling out to arm_cpu_do_interrupt()
      target-arm: Fix wrong AArch64 entry offset for EL2/EL3 target
      target-arm: Handle exception return from AArch64 to non-EL0 AArch32
      target-arm: Implement remaining illegal return event checks
      target-arm: ignore ELR_ELx[1] for exception return to 32-bit ARM mode
      target-arm: Implement FPEXC32_EL2 system register

 cpus.c                              |  13 +-
 cputlb.c                            |   9 +-
 exec.c                              | 103 ++++++++----
 hw/arm/pxa2xx.c                     |   2 +-
 hw/arm/spitz.c                      |   2 +-
 hw/arm/stellaris.c                  |   2 +-
 hw/arm/strongarm.c                  |   2 +-
 hw/arm/tosa.c                       |   2 +-
 hw/arm/virt.c                       |  59 ++++++-
 hw/arm/xilinx_zynq.c                |   2 +-
 hw/arm/xlnx-ep108.c                 |  16 ++
 hw/arm/xlnx-zynqmp.c                |  31 ++++
 hw/arm/z2.c                         |   2 +-
 hw/block/m25p80.c                   |   3 +-
 hw/core/qdev.c                      |   6 +
 hw/display/ads7846.c                |   2 +-
 hw/display/ssd0323.c                |   2 +-
 hw/intc/arm_gic.c                   |  35 ++++-
 hw/microblaze/petalogix_ml605_mmu.c |   2 +-
 hw/misc/max111x.c                   |   2 +-
 hw/misc/zynq-xadc.c                 |   2 +-
 hw/sd/ssi-sd.c                      |   2 +-
 hw/ssi/pl022.c                      |   2 +-
 hw/ssi/ssi.c                        |   2 +-
 hw/ssi/xilinx_spi.c                 |   2 +-
 hw/ssi/xilinx_spips.c               |  48 +-----
 include/exec/exec-all.h             |  69 ++++++++-
 include/exec/memory.h               |  18 +++
 include/hw/arm/virt.h               |   1 +
 include/hw/arm/xlnx-zynqmp.h        |   3 +
 include/hw/{ => ssi}/ssi.h          |  10 +-
 include/hw/ssi/xilinx_spips.h       |  72 +++++++++
 include/qom/cpu.h                   |  57 ++++++-
 memory.c                            |  27 ++++
 softmmu_template.h                  |   4 +-
 target-arm/cpu-qom.h                |   8 +-
 target-arm/cpu.c                    |  35 ++++-
 target-arm/cpu.h                    |  56 +++++--
 target-arm/cpu64.c                  |   3 -
 target-arm/helper-a64.c             | 104 -------------
 target-arm/helper.c                 | 301 +++++++++++++++++++++++++++++-------
 target-arm/op_helper.c              |  94 ++++++++---
 target-i386/cpu.c                   |   7 +-
 43 files changed, 909 insertions(+), 315 deletions(-)
 rename include/hw/{ => ssi}/ssi.h (96%)
 create mode 100644 include/hw/ssi/xilinx_spips.h

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

end of thread, other threads:[~2017-09-04 16:20 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-19 14:09 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 01/36] arm: Uniquely name imx25 I2C buses Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 02/36] block: m25p80: Add Quad Page Program 4byte Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 03/36] block: m25p80: Introduce die erase command Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 04/36] block: m25p80: Improve 1GiB Micron flash definition Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 05/36] target/arm: Handle VIRQ and VFIQ in arm_cpu_do_interrupt_aarch32() Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 06/36] target/arm: Implement DBGVCR32_EL2 system register Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 07/36] aspeed/smc: remove call to reset in realize function Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 08/36] aspeed/smc: remove call to aspeed_smc_update_cs() in reset function Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 09/36] aspeed/smc: rework the prototype of the AspeedSMCFlash helper routines Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 10/36] aspeed/smc: autostrap CE0/1 configuration Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 11/36] aspeed/smc: unfold the AspeedSMCController array Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 12/36] aspeed/smc: adjust the size of the register region Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 13/36] aspeed/smc: handle SPI flash Command mode Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 14/36] aspeed/smc: reset flash after each test Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 15/36] aspeed/smc: extend tests for Command mode Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 16/36] aspeed: use first FMC flash as a boot ROM Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 17/36] arm: virt: Fix segmentation fault when specifying an unsupported CPU Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 18/36] hw/arm/virt-acpi - reserve ECAM space as PNP0C02 device Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 19/36] hw/intc/arm_gicv3: Add external IRQ lines for VIRQ and VFIQ Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 20/36] hw/intc/arm_gic: " Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 21/36] target-arm: Expose output GPIO line for VCPU maintenance interrupt Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 22/36] hw/arm/virt: Wire VIRQ, VFIQ, maintenance irq lines from GIC to CPU Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 23/36] target-arm: Add ARMCPU fields for GIC CPU i/f config Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 24/36] hw/intc/gicv3: Add defines for ICH system register fields Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 25/36] hw/intc/gicv3: Add data fields for virtualization support Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 26/36] hw/intc/arm_gicv3: Add accessors for ICH_ system registers Peter Maydell
2017-01-26  9:35   ` Paolo Bonzini
2017-01-26  9:42     ` Thomas Huth
2017-01-19 14:09 ` [Qemu-devel] [PULL 27/36] hw/intc/arm_gicv3: Implement ICV_ registers which are just accessors Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 28/36] hw/intc/arm_gicv3: Implement ICV_ HPPIR, DIR and RPR registers Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 29/36] hw/intc/arm_gicv3: Implement ICV_ registers EOIR and IAR Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 30/36] hw/intc/arm_gicv3: Implement gicv3_cpuif_virt_update() Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 31/36] hw/intc/arm_gicv3: Implement EL2 traps for CPU i/f regs Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 32/36] hw/arm/virt: Support using SMC for PSCI Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 33/36] hw/arm/virt-acpi-build: use SMC if booting in EL2 Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 34/36] target/arm/psci.c: If EL2 implemented, start CPUs " Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 35/36] target-arm: Enable EL2 feature bit on A53 and A57 Peter Maydell
2017-01-19 14:09 ` [Qemu-devel] [PULL 36/36] hw/arm/virt: Add board property to enable EL2 Peter Maydell
  -- strict thread matches above, loose matches on Subject: below --
2017-09-04 14:39 [Qemu-devel] [PULL 00/36] target-arm queue Peter Maydell
2017-09-04 16:20 ` Peter Maydell
2017-09-04 12:25 Peter Maydell
2016-09-22 17:21 Peter Maydell
2016-09-22 19:58 ` no-reply
2016-09-23  9:57 ` Peter Maydell
2016-02-18 15:20 Peter Maydell
2016-02-18 15:50 ` Peter Maydell
2016-02-18 14:34 Peter Maydell
2016-02-18 15:19 ` Peter Maydell
2016-01-21 14:55 Peter Maydell
2016-01-21 15:53 ` 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.