qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PULL 00/36] target-arm queue
@ 2020-03-12 16:44 Peter Maydell
  2020-03-12 20:32 ` Peter Maydell
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2020-03-12 16:44 UTC (permalink / raw)
  To: qemu-devel

arm queue; dunno if this will be the last before softfreeze
or not, but anyway probably the last large one. New orangepi-pc
board model is the big item here.

thanks
-- PMM

The following changes since commit 67d9ef7d541c3d21a25796c51c26da096a433565:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-docs-20200312' into staging (2020-03-12 15:20:52 +0000)

are available in the Git repository at:

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

for you to fetch changes up to aca53be34ac3e7cac5f39396a51a338860a5a837:

  target/arm: kvm: Inject events at the last stage of sync (2020-03-12 16:31:10 +0000)

----------------------------------------------------------------
target-arm queue:
 * Fix various bugs that might result in an assert() due to
   incorrect hflags for M-profile CPUs
 * Fix Aspeed SMC Controller user-mode select handling
 * Report correct (with-tag) address in fault address register
   when TBI is enabled
 * cubieboard: make sure SOC object isn't leaked
 * fsl-imx25: Wire up eSDHC controllers
 * fsl-imx25: Wire up USB controllers
 * New board model: orangepi-pc (OrangePi PC)
 * ARM/KVM: if user doesn't select GIC version and the
   host kernel can only provide GICv3, use that, rather
   than defaulting to "fail because GICv2 isn't possible"
 * kvm: Only do KVM_SET_VCPU_EVENTS at the last stage of sync

----------------------------------------------------------------
Beata Michalska (1):
      target/arm: kvm: Inject events at the last stage of sync

Cédric Le Goater (2):
      aspeed/smc: Add some tracing
      aspeed/smc: Fix User mode select/unselect scheme

Eric Auger (6):
      hw/arm/virt: Document 'max' value in gic-version property description
      hw/arm/virt: Introduce VirtGICType enum type
      hw/arm/virt: Introduce finalize_gic_version()
      target/arm/kvm: Let kvm_arm_vgic_probe() return a bitmap
      hw/arm/virt: kvm: Restructure finalize_gic_version()
      hw/arm/virt: kvm: allow gicv3 by default if v2 cannot work

Guenter Roeck (2):
      hw/arm/fsl-imx25: Wire up eSDHC controllers
      hw/arm/fsl-imx25: Wire up USB controllers

Igor Mammedov (1):
      hw/arm/cubieboard: make sure SOC object isn't leaked

Niek Linnenbank (13):
      hw/arm: add Allwinner H3 System-on-Chip
      hw/arm: add Xunlong Orange Pi PC machine
      hw/arm/allwinner-h3: add Clock Control Unit
      hw/arm/allwinner-h3: add USB host controller
      hw/arm/allwinner-h3: add System Control module
      hw/arm/allwinner: add CPU Configuration module
      hw/arm/allwinner: add Security Identifier device
      hw/arm/allwinner: add SD/MMC host controller
      hw/arm/allwinner-h3: add EMAC ethernet device
      hw/arm/allwinner-h3: add Boot ROM support
      hw/arm/allwinner-h3: add SDRAM controller device
      hw/arm/allwinner: add RTC device support
      docs: add Orange Pi PC document

Peter Maydell (4):
      hw/intc/armv7m_nvic: Rebuild hflags on reset
      target/arm: Update hflags in trans_CPS_v7m()
      target/arm: Recalculate hflags correctly after writes to CONTROL
      target/arm: Fix some comment typos

Philippe Mathieu-Daudé (5):
      tests/boot_linux_console: Add a quick test for the OrangePi PC board
      tests/boot_linux_console: Add initrd test for the Orange Pi PC board
      tests/boot_linux_console: Add a SD card test for the OrangePi PC board
      tests/boot_linux_console: Add a SLOW test booting Ubuntu on OrangePi PC
      tests/boot_linux_console: Test booting NetBSD via U-Boot on OrangePi PC

Richard Henderson (2):
      target/arm: Check addresses for disabled regimes
      target/arm: Disable clean_data_tbi for system mode

 Makefile.objs                          |   1 +
 hw/arm/Makefile.objs                   |   1 +
 hw/misc/Makefile.objs                  |   5 +
 hw/net/Makefile.objs                   |   1 +
 hw/rtc/Makefile.objs                   |   1 +
 hw/sd/Makefile.objs                    |   1 +
 hw/usb/hcd-ehci.h                      |   1 +
 include/hw/arm/allwinner-a10.h         |   4 +
 include/hw/arm/allwinner-h3.h          | 161 ++++++
 include/hw/arm/fsl-imx25.h             |  18 +
 include/hw/arm/virt.h                  |  12 +-
 include/hw/misc/allwinner-cpucfg.h     |  52 ++
 include/hw/misc/allwinner-h3-ccu.h     |  66 +++
 include/hw/misc/allwinner-h3-dramc.h   | 106 ++++
 include/hw/misc/allwinner-h3-sysctrl.h |  67 +++
 include/hw/misc/allwinner-sid.h        |  60 +++
 include/hw/net/allwinner-sun8i-emac.h  |  99 ++++
 include/hw/rtc/allwinner-rtc.h         | 134 +++++
 include/hw/sd/allwinner-sdhost.h       | 135 +++++
 target/arm/helper.h                    |   1 +
 target/arm/kvm_arm.h                   |   3 +
 hw/arm/allwinner-a10.c                 |  19 +
 hw/arm/allwinner-h3.c                  | 465 ++++++++++++++++++
 hw/arm/cubieboard.c                    |  18 +
 hw/arm/fsl-imx25.c                     |  56 +++
 hw/arm/imx25_pdk.c                     |  16 +
 hw/arm/orangepi.c                      | 130 +++++
 hw/arm/virt.c                          | 145 ++++--
 hw/intc/armv7m_nvic.c                  |   6 +
 hw/misc/allwinner-cpucfg.c             | 282 +++++++++++
 hw/misc/allwinner-h3-ccu.c             | 242 +++++++++
 hw/misc/allwinner-h3-dramc.c           | 358 ++++++++++++++
 hw/misc/allwinner-h3-sysctrl.c         | 140 ++++++
 hw/misc/allwinner-sid.c                | 168 +++++++
 hw/net/allwinner-sun8i-emac.c          | 871 +++++++++++++++++++++++++++++++++
 hw/rtc/allwinner-rtc.c                 | 411 ++++++++++++++++
 hw/sd/allwinner-sdhost.c               | 854 ++++++++++++++++++++++++++++++++
 hw/ssi/aspeed_smc.c                    |  56 ++-
 hw/usb/hcd-ehci-sysbus.c               |  17 +
 target/arm/helper.c                    |  49 +-
 target/arm/kvm.c                       |  14 +-
 target/arm/kvm32.c                     |  15 +-
 target/arm/kvm64.c                     |  15 +-
 target/arm/translate-a64.c             |  11 +
 target/arm/translate.c                 |  14 +-
 MAINTAINERS                            |   9 +
 default-configs/arm-softmmu.mak        |   1 +
 docs/system/arm/orangepi.rst           | 253 ++++++++++
 docs/system/target-arm.rst             |   2 +
 hw/arm/Kconfig                         |  12 +
 hw/misc/trace-events                   |  19 +
 hw/net/Kconfig                         |   3 +
 hw/net/trace-events                    |  10 +
 hw/rtc/trace-events                    |   4 +
 hw/sd/trace-events                     |   7 +
 hw/ssi/trace-events                    |  10 +
 tests/acceptance/boot_linux_console.py | 230 +++++++++
 57 files changed, 5787 insertions(+), 74 deletions(-)
 create mode 100644 include/hw/arm/allwinner-h3.h
 create mode 100644 include/hw/misc/allwinner-cpucfg.h
 create mode 100644 include/hw/misc/allwinner-h3-ccu.h
 create mode 100644 include/hw/misc/allwinner-h3-dramc.h
 create mode 100644 include/hw/misc/allwinner-h3-sysctrl.h
 create mode 100644 include/hw/misc/allwinner-sid.h
 create mode 100644 include/hw/net/allwinner-sun8i-emac.h
 create mode 100644 include/hw/rtc/allwinner-rtc.h
 create mode 100644 include/hw/sd/allwinner-sdhost.h
 create mode 100644 hw/arm/allwinner-h3.c
 create mode 100644 hw/arm/orangepi.c
 create mode 100644 hw/misc/allwinner-cpucfg.c
 create mode 100644 hw/misc/allwinner-h3-ccu.c
 create mode 100644 hw/misc/allwinner-h3-dramc.c
 create mode 100644 hw/misc/allwinner-h3-sysctrl.c
 create mode 100644 hw/misc/allwinner-sid.c
 create mode 100644 hw/net/allwinner-sun8i-emac.c
 create mode 100644 hw/rtc/allwinner-rtc.c
 create mode 100644 hw/sd/allwinner-sdhost.c
 create mode 100644 docs/system/arm/orangepi.rst
 create mode 100644 hw/ssi/trace-events


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

* Re: [PULL 00/36] target-arm queue
  2020-03-12 16:44 Peter Maydell
@ 2020-03-12 20:32 ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-03-12 20:32 UTC (permalink / raw)
  To: QEMU Developers

On Thu, 12 Mar 2020 at 16:45, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> arm queue; dunno if this will be the last before softfreeze
> or not, but anyway probably the last large one. New orangepi-pc
> board model is the big item here.
>
> thanks
> -- PMM
>
> The following changes since commit 67d9ef7d541c3d21a25796c51c26da096a433565:
>
>   Merge remote-tracking branch 'remotes/pmaydell/tags/pull-docs-20200312' into staging (2020-03-12 15:20:52 +0000)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200312
>
> for you to fetch changes up to aca53be34ac3e7cac5f39396a51a338860a5a837:
>
>   target/arm: kvm: Inject events at the last stage of sync (2020-03-12 16:31:10 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * Fix various bugs that might result in an assert() due to
>    incorrect hflags for M-profile CPUs
>  * Fix Aspeed SMC Controller user-mode select handling
>  * Report correct (with-tag) address in fault address register
>    when TBI is enabled
>  * cubieboard: make sure SOC object isn't leaked
>  * fsl-imx25: Wire up eSDHC controllers
>  * fsl-imx25: Wire up USB controllers
>  * New board model: orangepi-pc (OrangePi PC)
>  * ARM/KVM: if user doesn't select GIC version and the
>    host kernel can only provide GICv3, use that, rather
>    than defaulting to "fail because GICv2 isn't possible"
>  * kvm: Only do KVM_SET_VCPU_EVENTS at the last stage of sync


Applied, thanks.

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

-- PMM


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

* [PULL 00/36] target-arm queue
@ 2020-09-14 14:06 Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-09-14 14:06 UTC (permalink / raw)
  To: qemu-devel

Nuvoton new board models, and some more minor stuff. I also put
in the deprecation patches for unicore32 and lm32.

thanks
-- PMM

The following changes since commit a68694cd1f3e5448cca814ff39b871f9ebd71ed5:

  Merge remote-tracking branch 'remotes/philmd-gitlab/tags/edk2-next-20200914' into staging (2020-09-14 12:18:58 +0100)

are available in the Git repository at:

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

for you to fetch changes up to dd44ae00fc5342ed99acb68ec3508f76a71d523a:

  MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller (2020-09-14 14:27:08 +0100)

----------------------------------------------------------------
target-arm queue:
 * hw/misc/a9scu: Do not allow invalid CPU count
 * hw/misc/a9scu: Minor cleanups
 * hw/timer/armv7m_systick: assert that board code set system_clock_scale
 * decodetree: Improve identifier matching
 * target/arm: Clean up neon fp insn size field decode
 * target/arm: Remove KVM support for 32-bit Arm hosts
 * hw/arm/mps2: New board models mps2-an386, mps2-an500
 * Deprecate Unicore32 port
 * Deprecate lm32 port
 * target/arm: Count PMU events when MDCR.SPME is set
 * hw/arm: versal-virt: Correct the tx/rx GEM clocks
 * New Nuvoton iBMC board models npcm750-evb, quanta-gsj
 * xlnx-zynqmp: implement ZynqMP CAN controllers

----------------------------------------------------------------
Aaron Lindsay (1):
      target/arm: Count PMU events when MDCR.SPME is set

Edgar E. Iglesias (1):
      hw/arm: versal-virt: Correct the tx/rx GEM clocks

Havard Skinnemoen (14):
      hw/misc: Add NPCM7xx System Global Control Registers device model
      hw/misc: Add NPCM7xx Clock Controller device model
      hw/timer: Add NPCM7xx Timer device model
      hw/arm: Add NPCM730 and NPCM750 SoC models
      hw/arm: Add two NPCM7xx-based machines
      roms: Add virtual Boot ROM for NPCM7xx SoCs
      hw/arm: Load -bios image as a boot ROM for npcm7xx
      hw/nvram: NPCM7xx OTP device model
      hw/mem: Stubbed out NPCM7xx Memory Controller model
      hw/ssi: NPCM7xx Flash Interface Unit device model
      hw/arm: Wire up BMC boot flash for npcm750-evb and quanta-gsj
      hw/arm/npcm7xx: add board setup stub for CPU and UART clocks
      docs/system: Add Nuvoton machine documentation
      tests/acceptance: console boot tests for quanta-gsj

Peter Maydell (11):
      hw/timer/armv7m_systick: assert that board code set system_clock_scale
      target/arm: Convert Neon 3-same-fp size field to MO_* in decode
      target/arm: Convert Neon VCVT fp size field to MO_* in decode
      target/arm: Convert VCMLA, VCADD size field to MO_* in decode
      target/arm: Remove KVM support for 32-bit Arm hosts
      target/arm: Remove no-longer-reachable 32-bit KVM code
      hw/arm/mps2: New board model mps2-an386
      hw/arm/mps2: New board model mps2-an500
      docs/system/arm/mps2.rst: Make board list consistent
      Deprecate Unicore32 port
      Deprecate lm32 port

Philippe Mathieu-Daudé (4):
      hw/misc/a9scu: Do not allow invalid CPU count
      hw/misc/a9scu: Simplify setting MemoryRegionOps::valid fields
      hw/misc/a9scu: Simplify setting MemoryRegionOps::impl fields
      hw/misc/a9scu: Report unimplemented accesses with qemu_log_mask(UNIMP)

Richard Henderson (1):
      decodetree: Improve identifier matching

Vikram Garhwal (4):
      hw/net/can: Introduce Xilinx ZynqMP CAN controller
      xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers
      tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller
      MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller

 docs/system/arm/mps2.rst               |   20 +-
 docs/system/arm/nuvoton.rst            |   92 +++
 docs/system/deprecated.rst             |   32 +-
 docs/system/target-arm.rst             |    1 +
 configure                              |    2 +-
 default-configs/arm-softmmu.mak        |    1 +
 include/hw/arm/npcm7xx.h               |  112 +++
 include/hw/arm/xlnx-zynqmp.h           |    8 +
 include/hw/mem/npcm7xx_mc.h            |   36 +
 include/hw/misc/npcm7xx_clk.h          |   48 ++
 include/hw/misc/npcm7xx_gcr.h          |   43 ++
 include/hw/net/xlnx-zynqmp-can.h       |   78 +++
 include/hw/nvram/npcm7xx_otp.h         |   79 +++
 include/hw/ssi/npcm7xx_fiu.h           |   73 ++
 include/hw/timer/npcm7xx_timer.h       |   78 +++
 target/arm/kvm-consts.h                |    7 -
 target/arm/kvm_arm.h                   |    6 -
 target/arm/neon-dp.decode              |   18 +-
 target/arm/neon-shared.decode          |   18 +-
 tests/decode/succ_ident1.decode        |    7 +
 hw/arm/mps2.c                          |   97 ++-
 hw/arm/npcm7xx.c                       |  532 +++++++++++++++
 hw/arm/npcm7xx_boards.c                |  197 ++++++
 hw/arm/xlnx-versal-virt.c              |    2 +-
 hw/arm/xlnx-zcu102.c                   |   20 +
 hw/arm/xlnx-zynqmp.c                   |   34 +
 hw/mem/npcm7xx_mc.c                    |   84 +++
 hw/misc/a9scu.c                        |   59 +-
 hw/misc/npcm7xx_clk.c                  |  266 ++++++++
 hw/misc/npcm7xx_gcr.c                  |  269 ++++++++
 hw/net/can/xlnx-zynqmp-can.c           | 1165 ++++++++++++++++++++++++++++++++
 hw/nvram/npcm7xx_otp.c                 |  440 ++++++++++++
 hw/ssi/npcm7xx_fiu.c                   |  572 ++++++++++++++++
 hw/timer/armv7m_systick.c              |    8 +
 hw/timer/npcm7xx_timer.c               |  543 +++++++++++++++
 target/arm/cpu.c                       |  101 ++-
 target/arm/helper.c                    |    2 +-
 target/arm/kvm.c                       |    7 -
 target/arm/kvm32.c                     |  595 ----------------
 tests/qtest/xlnx-can-test.c            |  359 ++++++++++
 .gitmodules                            |    3 +
 MAINTAINERS                            |   18 +
 hw/arm/Kconfig                         |    9 +
 hw/arm/meson.build                     |    1 +
 hw/mem/meson.build                     |    1 +
 hw/misc/meson.build                    |    4 +
 hw/misc/trace-events                   |    8 +
 hw/net/can/meson.build                 |    1 +
 hw/nvram/meson.build                   |    1 +
 hw/ssi/meson.build                     |    1 +
 hw/ssi/trace-events                    |   11 +
 hw/timer/meson.build                   |    1 +
 hw/timer/trace-events                  |    5 +
 pc-bios/README                         |    6 +
 pc-bios/meson.build                    |    1 +
 pc-bios/npcm7xx_bootrom.bin            |  Bin 0 -> 768 bytes
 roms/Makefile                          |    7 +
 roms/vbootrom                          |    1 +
 scripts/decodetree.py                  |   46 +-
 target/arm/meson.build                 |    5 +-
 target/arm/translate-neon.c.inc        |   42 +-
 tests/acceptance/boot_linux_console.py |   83 +++
 tests/qtest/meson.build                |    1 +
 63 files changed, 5584 insertions(+), 783 deletions(-)
 create mode 100644 docs/system/arm/nuvoton.rst
 create mode 100644 include/hw/arm/npcm7xx.h
 create mode 100644 include/hw/mem/npcm7xx_mc.h
 create mode 100644 include/hw/misc/npcm7xx_clk.h
 create mode 100644 include/hw/misc/npcm7xx_gcr.h
 create mode 100644 include/hw/net/xlnx-zynqmp-can.h
 create mode 100644 include/hw/nvram/npcm7xx_otp.h
 create mode 100644 include/hw/ssi/npcm7xx_fiu.h
 create mode 100644 include/hw/timer/npcm7xx_timer.h
 create mode 100644 tests/decode/succ_ident1.decode
 create mode 100644 hw/arm/npcm7xx.c
 create mode 100644 hw/arm/npcm7xx_boards.c
 create mode 100644 hw/mem/npcm7xx_mc.c
 create mode 100644 hw/misc/npcm7xx_clk.c
 create mode 100644 hw/misc/npcm7xx_gcr.c
 create mode 100644 hw/net/can/xlnx-zynqmp-can.c
 create mode 100644 hw/nvram/npcm7xx_otp.c
 create mode 100644 hw/ssi/npcm7xx_fiu.c
 create mode 100644 hw/timer/npcm7xx_timer.c
 delete mode 100644 target/arm/kvm32.c
 create mode 100644 tests/qtest/xlnx-can-test.c
 create mode 100644 pc-bios/npcm7xx_bootrom.bin
 create mode 160000 roms/vbootrom


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

* [PULL 00/36] target-arm queue
@ 2020-12-10 11:47 Peter Maydell
  2020-12-10 11:47 ` [PULL 01/36] hw/arm/smmuv3: Fix up L1STD_SPAN decoding Peter Maydell
                   ` (36 more replies)
  0 siblings, 37 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

First pullreq for 6.0: mostly my v8.1M work, plus some other
bits and pieces. (I still have a lot of stuff in my to-review
folder, which I may or may not get to before the Christmas break...)

thanks
-- PMM

The following changes since commit 5e7b204dbfae9a562fc73684986f936b97f63877:

  Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2020-12-09 20:08:54 +0000)

are available in the Git repository at:

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

for you to fetch changes up to 71f916be1c7e9ede0e37d9cabc781b5a9e8638ff:

  hw/arm/armv7m: Correct typo in QOM object name (2020-12-10 11:44:56 +0000)

----------------------------------------------------------------
target-arm queue:
 * hw/arm/smmuv3: Fix up L1STD_SPAN decoding
 * xlnx-zynqmp: Support Xilinx ZynqMP CAN controllers
 * sbsa-ref: allow to use Cortex-A53/57/72 cpus
 * Various minor code cleanups
 * hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault
 * Implement more pieces of ARMv8.1M support

----------------------------------------------------------------
Alex Chen (4):
      i.MX25: Fix bad printf format specifiers
      i.MX31: Fix bad printf format specifiers
      i.MX6: Fix bad printf format specifiers
      i.MX6ul: Fix bad printf format specifiers

Havard Skinnemoen (1):
      tests/qtest/npcm7xx_rng-test: dump random data on failure

Kunkun Jiang (1):
      hw/arm/smmuv3: Fix up L1STD_SPAN decoding

Marcin Juszkiewicz (1):
      sbsa-ref: allow to use Cortex-A53/57/72 cpus

Peter Maydell (25):
      hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault
      target/arm: Implement v8.1M PXN extension
      target/arm: Don't clobber ID_PFR1.Security on M-profile cores
      target/arm: Implement VSCCLRM insn
      target/arm: Implement CLRM instruction
      target/arm: Enforce M-profile VMRS/VMSR register restrictions
      target/arm: Refactor M-profile VMSR/VMRS handling
      target/arm: Move general-use constant expanders up in translate.c
      target/arm: Implement VLDR/VSTR system register
      target/arm: Implement M-profile FPSCR_nzcvqc
      target/arm: Use new FPCR_NZCV_MASK constant
      target/arm: Factor out preserve-fp-state from full_vfp_access_check()
      target/arm: Implement FPCXT_S fp system register
      hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M
      target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry
      target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures
      target/arm: Implement v8.1M REVIDR register
      target/arm: Implement new v8.1M NOCP check for exception return
      target/arm: Implement new v8.1M VLLDM and VLSTM encodings
      hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit
      target/arm: Implement CCR_S.TRD behaviour for SG insns
      hw/intc/armv7m_nvic: Fix "return from inactive handler" check
      target/arm: Implement M-profile "minimal RAS implementation"
      hw/intc/armv7m_nvic: Implement read/write for RAS register block
      hw/arm/armv7m: Correct typo in QOM object name

Vikram Garhwal (4):
      hw/net/can: Introduce Xilinx ZynqMP CAN controller
      xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers
      tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller
      MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller

 meson.build                      |    1 +
 hw/arm/smmuv3-internal.h         |    2 +-
 hw/net/can/trace.h               |    1 +
 include/hw/arm/xlnx-zynqmp.h     |    8 +
 include/hw/intc/armv7m_nvic.h    |    2 +
 include/hw/net/xlnx-zynqmp-can.h |   78 +++
 target/arm/cpu.h                 |   46 ++
 target/arm/m-nocp.decode         |   10 +-
 target/arm/t32.decode            |   10 +-
 target/arm/vfp.decode            |   14 +
 hw/arm/armv7m.c                  |    4 +-
 hw/arm/sbsa-ref.c                |   23 +-
 hw/arm/xlnx-zcu102.c             |   20 +
 hw/arm/xlnx-zynqmp.c             |   34 ++
 hw/intc/armv7m_nvic.c            |  246 ++++++--
 hw/misc/imx25_ccm.c              |   12 +-
 hw/misc/imx31_ccm.c              |   14 +-
 hw/misc/imx6_ccm.c               |   20 +-
 hw/misc/imx6_src.c               |    2 +-
 hw/misc/imx6ul_ccm.c             |    4 +-
 hw/misc/imx_ccm.c                |    4 +-
 hw/net/can/xlnx-zynqmp-can.c     | 1161 ++++++++++++++++++++++++++++++++++++++
 target/arm/cpu.c                 |    5 +-
 target/arm/helper.c              |    7 +-
 target/arm/m_helper.c            |  130 ++++-
 target/arm/translate.c           |  105 +++-
 tests/qtest/npcm7xx_rng-test.c   |   12 +
 tests/qtest/xlnx-can-test.c      |  360 ++++++++++++
 MAINTAINERS                      |    8 +
 hw/Kconfig                       |    1 +
 hw/net/can/meson.build           |    1 +
 hw/net/can/trace-events          |    9 +
 target/arm/translate-vfp.c.inc   |  511 ++++++++++++++++-
 tests/qtest/meson.build          |    1 +
 34 files changed, 2713 insertions(+), 153 deletions(-)
 create mode 100644 hw/net/can/trace.h
 create mode 100644 include/hw/net/xlnx-zynqmp-can.h
 create mode 100644 hw/net/can/xlnx-zynqmp-can.c
 create mode 100644 tests/qtest/xlnx-can-test.c
 create mode 100644 hw/net/can/trace-events


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

* [PULL 01/36] hw/arm/smmuv3: Fix up L1STD_SPAN decoding
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 02/36] hw/net/can: Introduce Xilinx ZynqMP CAN controller Peter Maydell
                   ` (35 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Kunkun Jiang <jiangkunkun@huawei.com>

Accroding to the SMMUv3 spec, the SPAN field of Level1 Stream Table
Descriptor is 5 bits([4:0]).

Fixes: 9bde7f0674f(hw/arm/smmuv3: Implement translate callback)
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
Message-id: 20201124023711.1184-1-jiangkunkun@huawei.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/smmuv3-internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index fa3c088972e..b6f7e53b7c7 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -633,6 +633,6 @@ static inline uint64_t l1std_l2ptr(STEDesc *desc)
     return hi << 32 | lo;
 }
 
-#define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 4))
+#define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 5))
 
 #endif
-- 
2.20.1



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

* [PULL 02/36] hw/net/can: Introduce Xilinx ZynqMP CAN controller
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
  2020-12-10 11:47 ` [PULL 01/36] hw/arm/smmuv3: Fix up L1STD_SPAN decoding Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 03/36] xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers Peter Maydell
                   ` (34 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Vikram Garhwal <fnu.vikram@xilinx.com>

The Xilinx ZynqMP CAN controller is developed based on SocketCAN, QEMU CAN bus
implementation. Bus connection and socketCAN connection for each CAN module
can be set through command lines.

Example for using single CAN:
    -object can-bus,id=canbus0 \
    -machine xlnx-zcu102.canbus0=canbus0 \
    -object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0

Example for connecting both CAN to same virtual CAN on host machine:
    -object can-bus,id=canbus0 -object can-bus,id=canbus1 \
    -machine xlnx-zcu102.canbus0=canbus0 \
    -machine xlnx-zcu102.canbus1=canbus1 \
    -object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0 \
    -object can-host-socketcan,id=socketcan1,if=vcan0,canbus=canbus1

To create virtual CAN on the host machine, please check the QEMU CAN docs:
https://github.com/qemu/qemu/blob/master/docs/can.txt

Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
Message-id: 1605728926-352690-2-git-send-email-fnu.vikram@xilinx.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 meson.build                      |    1 +
 hw/net/can/trace.h               |    1 +
 include/hw/net/xlnx-zynqmp-can.h |   78 ++
 hw/net/can/xlnx-zynqmp-can.c     | 1161 ++++++++++++++++++++++++++++++
 hw/Kconfig                       |    1 +
 hw/net/can/meson.build           |    1 +
 hw/net/can/trace-events          |    9 +
 7 files changed, 1252 insertions(+)
 create mode 100644 hw/net/can/trace.h
 create mode 100644 include/hw/net/xlnx-zynqmp-can.h
 create mode 100644 hw/net/can/xlnx-zynqmp-can.c
 create mode 100644 hw/net/can/trace-events

diff --git a/meson.build b/meson.build
index 732b29a1f37..9ea05ab49fa 100644
--- a/meson.build
+++ b/meson.build
@@ -1433,6 +1433,7 @@ if have_system
     'hw/misc',
     'hw/misc/macio',
     'hw/net',
+    'hw/net/can',
     'hw/nvram',
     'hw/pci',
     'hw/pci-host',
diff --git a/hw/net/can/trace.h b/hw/net/can/trace.h
new file mode 100644
index 00000000000..d391c649012
--- /dev/null
+++ b/hw/net/can/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-hw_net_can.h"
diff --git a/include/hw/net/xlnx-zynqmp-can.h b/include/hw/net/xlnx-zynqmp-can.h
new file mode 100644
index 00000000000..eb1558708bb
--- /dev/null
+++ b/include/hw/net/xlnx-zynqmp-can.h
@@ -0,0 +1,78 @@
+/*
+ * QEMU model of the Xilinx ZynqMP CAN controller.
+ *
+ * Copyright (c) 2020 Xilinx Inc.
+ *
+ * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
+ *
+ * Based on QEMU CAN Device emulation implemented by Jin Yang, Deniz Eren and
+ * Pavel Pisa.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef XLNX_ZYNQMP_CAN_H
+#define XLNX_ZYNQMP_CAN_H
+
+#include "hw/register.h"
+#include "net/can_emu.h"
+#include "net/can_host.h"
+#include "qemu/fifo32.h"
+#include "hw/ptimer.h"
+#include "hw/qdev-clock.h"
+
+#define TYPE_XLNX_ZYNQMP_CAN "xlnx.zynqmp-can"
+
+#define XLNX_ZYNQMP_CAN(obj) \
+     OBJECT_CHECK(XlnxZynqMPCANState, (obj), TYPE_XLNX_ZYNQMP_CAN)
+
+#define MAX_CAN_CTRLS      2
+#define XLNX_ZYNQMP_CAN_R_MAX     (0x84 / 4)
+#define MAILBOX_CAPACITY   64
+#define CAN_TIMER_MAX  0XFFFFUL
+#define CAN_DEFAULT_CLOCK (24 * 1000 * 1000)
+
+/* Each CAN_FRAME will have 4 * 32bit size. */
+#define CAN_FRAME_SIZE     4
+#define RXFIFO_SIZE        (MAILBOX_CAPACITY * CAN_FRAME_SIZE)
+
+typedef struct XlnxZynqMPCANState {
+    SysBusDevice        parent_obj;
+    MemoryRegion        iomem;
+
+    qemu_irq            irq;
+
+    CanBusClientState   bus_client;
+    CanBusState         *canbus;
+
+    struct {
+        uint32_t        ext_clk_freq;
+    } cfg;
+
+    RegisterInfo        reg_info[XLNX_ZYNQMP_CAN_R_MAX];
+    uint32_t            regs[XLNX_ZYNQMP_CAN_R_MAX];
+
+    Fifo32              rx_fifo;
+    Fifo32              tx_fifo;
+    Fifo32              txhpb_fifo;
+
+    ptimer_state        *can_timer;
+} XlnxZynqMPCANState;
+
+#endif
diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c
new file mode 100644
index 00000000000..affa21a5ed3
--- /dev/null
+++ b/hw/net/can/xlnx-zynqmp-can.c
@@ -0,0 +1,1161 @@
+/*
+ * QEMU model of the Xilinx ZynqMP CAN controller.
+ * This implementation is based on the following datasheet:
+ * https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
+ *
+ * Copyright (c) 2020 Xilinx Inc.
+ *
+ * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
+ *
+ * Based on QEMU CAN Device emulation implemented by Jin Yang, Deniz Eren and
+ * Pavel Pisa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/register.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/cutils.h"
+#include "sysemu/sysemu.h"
+#include "migration/vmstate.h"
+#include "hw/qdev-properties.h"
+#include "net/can_emu.h"
+#include "net/can_host.h"
+#include "qemu/event_notifier.h"
+#include "qom/object_interfaces.h"
+#include "hw/net/xlnx-zynqmp-can.h"
+#include "trace.h"
+
+#ifndef XLNX_ZYNQMP_CAN_ERR_DEBUG
+#define XLNX_ZYNQMP_CAN_ERR_DEBUG 0
+#endif
+
+#define MAX_DLC            8
+#undef ERROR
+
+REG32(SOFTWARE_RESET_REGISTER, 0x0)
+    FIELD(SOFTWARE_RESET_REGISTER, CEN, 1, 1)
+    FIELD(SOFTWARE_RESET_REGISTER, SRST, 0, 1)
+REG32(MODE_SELECT_REGISTER, 0x4)
+    FIELD(MODE_SELECT_REGISTER, SNOOP, 2, 1)
+    FIELD(MODE_SELECT_REGISTER, LBACK, 1, 1)
+    FIELD(MODE_SELECT_REGISTER, SLEEP, 0, 1)
+REG32(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, 0x8)
+    FIELD(ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER, BRP, 0, 8)
+REG32(ARBITRATION_PHASE_BIT_TIMING_REGISTER, 0xc)
+    FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, SJW, 7, 2)
+    FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, TS2, 4, 3)
+    FIELD(ARBITRATION_PHASE_BIT_TIMING_REGISTER, TS1, 0, 4)
+REG32(ERROR_COUNTER_REGISTER, 0x10)
+    FIELD(ERROR_COUNTER_REGISTER, REC, 8, 8)
+    FIELD(ERROR_COUNTER_REGISTER, TEC, 0, 8)
+REG32(ERROR_STATUS_REGISTER, 0x14)
+    FIELD(ERROR_STATUS_REGISTER, ACKER, 4, 1)
+    FIELD(ERROR_STATUS_REGISTER, BERR, 3, 1)
+    FIELD(ERROR_STATUS_REGISTER, STER, 2, 1)
+    FIELD(ERROR_STATUS_REGISTER, FMER, 1, 1)
+    FIELD(ERROR_STATUS_REGISTER, CRCER, 0, 1)
+REG32(STATUS_REGISTER, 0x18)
+    FIELD(STATUS_REGISTER, SNOOP, 12, 1)
+    FIELD(STATUS_REGISTER, ACFBSY, 11, 1)
+    FIELD(STATUS_REGISTER, TXFLL, 10, 1)
+    FIELD(STATUS_REGISTER, TXBFLL, 9, 1)
+    FIELD(STATUS_REGISTER, ESTAT, 7, 2)
+    FIELD(STATUS_REGISTER, ERRWRN, 6, 1)
+    FIELD(STATUS_REGISTER, BBSY, 5, 1)
+    FIELD(STATUS_REGISTER, BIDLE, 4, 1)
+    FIELD(STATUS_REGISTER, NORMAL, 3, 1)
+    FIELD(STATUS_REGISTER, SLEEP, 2, 1)
+    FIELD(STATUS_REGISTER, LBACK, 1, 1)
+    FIELD(STATUS_REGISTER, CONFIG, 0, 1)
+REG32(INTERRUPT_STATUS_REGISTER, 0x1c)
+    FIELD(INTERRUPT_STATUS_REGISTER, TXFEMP, 14, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, TXFWMEMP, 13, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, RXFWMFLL, 12, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, WKUP, 11, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, SLP, 10, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, BSOFF, 9, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, ERROR, 8, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, RXNEMP, 7, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, RXOFLW, 6, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, RXUFLW, 5, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, RXOK, 4, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, TXBFLL, 3, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, TXFLL, 2, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, TXOK, 1, 1)
+    FIELD(INTERRUPT_STATUS_REGISTER, ARBLST, 0, 1)
+REG32(INTERRUPT_ENABLE_REGISTER, 0x20)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ETXFEMP, 14, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ETXFWMEMP, 13, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ERXFWMFLL, 12, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, EWKUP, 11, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ESLP, 10, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, EBSOFF, 9, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, EERROR, 8, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ERXNEMP, 7, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ERXOFLW, 6, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ERXUFLW, 5, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ERXOK, 4, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ETXBFLL, 3, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ETXFLL, 2, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, ETXOK, 1, 1)
+    FIELD(INTERRUPT_ENABLE_REGISTER, EARBLST, 0, 1)
+REG32(INTERRUPT_CLEAR_REGISTER, 0x24)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CTXFEMP, 14, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CTXFWMEMP, 13, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CRXFWMFLL, 12, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CWKUP, 11, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CSLP, 10, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CBSOFF, 9, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CERROR, 8, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CRXNEMP, 7, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CRXOFLW, 6, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CRXUFLW, 5, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CRXOK, 4, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CTXBFLL, 3, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CTXFLL, 2, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CTXOK, 1, 1)
+    FIELD(INTERRUPT_CLEAR_REGISTER, CARBLST, 0, 1)
+REG32(TIMESTAMP_REGISTER, 0x28)
+    FIELD(TIMESTAMP_REGISTER, CTS, 0, 1)
+REG32(WIR, 0x2c)
+    FIELD(WIR, EW, 8, 8)
+    FIELD(WIR, FW, 0, 8)
+REG32(TXFIFO_ID, 0x30)
+    FIELD(TXFIFO_ID, IDH, 21, 11)
+    FIELD(TXFIFO_ID, SRRRTR, 20, 1)
+    FIELD(TXFIFO_ID, IDE, 19, 1)
+    FIELD(TXFIFO_ID, IDL, 1, 18)
+    FIELD(TXFIFO_ID, RTR, 0, 1)
+REG32(TXFIFO_DLC, 0x34)
+    FIELD(TXFIFO_DLC, DLC, 28, 4)
+REG32(TXFIFO_DATA1, 0x38)
+    FIELD(TXFIFO_DATA1, DB0, 24, 8)
+    FIELD(TXFIFO_DATA1, DB1, 16, 8)
+    FIELD(TXFIFO_DATA1, DB2, 8, 8)
+    FIELD(TXFIFO_DATA1, DB3, 0, 8)
+REG32(TXFIFO_DATA2, 0x3c)
+    FIELD(TXFIFO_DATA2, DB4, 24, 8)
+    FIELD(TXFIFO_DATA2, DB5, 16, 8)
+    FIELD(TXFIFO_DATA2, DB6, 8, 8)
+    FIELD(TXFIFO_DATA2, DB7, 0, 8)
+REG32(TXHPB_ID, 0x40)
+    FIELD(TXHPB_ID, IDH, 21, 11)
+    FIELD(TXHPB_ID, SRRRTR, 20, 1)
+    FIELD(TXHPB_ID, IDE, 19, 1)
+    FIELD(TXHPB_ID, IDL, 1, 18)
+    FIELD(TXHPB_ID, RTR, 0, 1)
+REG32(TXHPB_DLC, 0x44)
+    FIELD(TXHPB_DLC, DLC, 28, 4)
+REG32(TXHPB_DATA1, 0x48)
+    FIELD(TXHPB_DATA1, DB0, 24, 8)
+    FIELD(TXHPB_DATA1, DB1, 16, 8)
+    FIELD(TXHPB_DATA1, DB2, 8, 8)
+    FIELD(TXHPB_DATA1, DB3, 0, 8)
+REG32(TXHPB_DATA2, 0x4c)
+    FIELD(TXHPB_DATA2, DB4, 24, 8)
+    FIELD(TXHPB_DATA2, DB5, 16, 8)
+    FIELD(TXHPB_DATA2, DB6, 8, 8)
+    FIELD(TXHPB_DATA2, DB7, 0, 8)
+REG32(RXFIFO_ID, 0x50)
+    FIELD(RXFIFO_ID, IDH, 21, 11)
+    FIELD(RXFIFO_ID, SRRRTR, 20, 1)
+    FIELD(RXFIFO_ID, IDE, 19, 1)
+    FIELD(RXFIFO_ID, IDL, 1, 18)
+    FIELD(RXFIFO_ID, RTR, 0, 1)
+REG32(RXFIFO_DLC, 0x54)
+    FIELD(RXFIFO_DLC, DLC, 28, 4)
+    FIELD(RXFIFO_DLC, RXT, 0, 16)
+REG32(RXFIFO_DATA1, 0x58)
+    FIELD(RXFIFO_DATA1, DB0, 24, 8)
+    FIELD(RXFIFO_DATA1, DB1, 16, 8)
+    FIELD(RXFIFO_DATA1, DB2, 8, 8)
+    FIELD(RXFIFO_DATA1, DB3, 0, 8)
+REG32(RXFIFO_DATA2, 0x5c)
+    FIELD(RXFIFO_DATA2, DB4, 24, 8)
+    FIELD(RXFIFO_DATA2, DB5, 16, 8)
+    FIELD(RXFIFO_DATA2, DB6, 8, 8)
+    FIELD(RXFIFO_DATA2, DB7, 0, 8)
+REG32(AFR, 0x60)
+    FIELD(AFR, UAF4, 3, 1)
+    FIELD(AFR, UAF3, 2, 1)
+    FIELD(AFR, UAF2, 1, 1)
+    FIELD(AFR, UAF1, 0, 1)
+REG32(AFMR1, 0x64)
+    FIELD(AFMR1, AMIDH, 21, 11)
+    FIELD(AFMR1, AMSRR, 20, 1)
+    FIELD(AFMR1, AMIDE, 19, 1)
+    FIELD(AFMR1, AMIDL, 1, 18)
+    FIELD(AFMR1, AMRTR, 0, 1)
+REG32(AFIR1, 0x68)
+    FIELD(AFIR1, AIIDH, 21, 11)
+    FIELD(AFIR1, AISRR, 20, 1)
+    FIELD(AFIR1, AIIDE, 19, 1)
+    FIELD(AFIR1, AIIDL, 1, 18)
+    FIELD(AFIR1, AIRTR, 0, 1)
+REG32(AFMR2, 0x6c)
+    FIELD(AFMR2, AMIDH, 21, 11)
+    FIELD(AFMR2, AMSRR, 20, 1)
+    FIELD(AFMR2, AMIDE, 19, 1)
+    FIELD(AFMR2, AMIDL, 1, 18)
+    FIELD(AFMR2, AMRTR, 0, 1)
+REG32(AFIR2, 0x70)
+    FIELD(AFIR2, AIIDH, 21, 11)
+    FIELD(AFIR2, AISRR, 20, 1)
+    FIELD(AFIR2, AIIDE, 19, 1)
+    FIELD(AFIR2, AIIDL, 1, 18)
+    FIELD(AFIR2, AIRTR, 0, 1)
+REG32(AFMR3, 0x74)
+    FIELD(AFMR3, AMIDH, 21, 11)
+    FIELD(AFMR3, AMSRR, 20, 1)
+    FIELD(AFMR3, AMIDE, 19, 1)
+    FIELD(AFMR3, AMIDL, 1, 18)
+    FIELD(AFMR3, AMRTR, 0, 1)
+REG32(AFIR3, 0x78)
+    FIELD(AFIR3, AIIDH, 21, 11)
+    FIELD(AFIR3, AISRR, 20, 1)
+    FIELD(AFIR3, AIIDE, 19, 1)
+    FIELD(AFIR3, AIIDL, 1, 18)
+    FIELD(AFIR3, AIRTR, 0, 1)
+REG32(AFMR4, 0x7c)
+    FIELD(AFMR4, AMIDH, 21, 11)
+    FIELD(AFMR4, AMSRR, 20, 1)
+    FIELD(AFMR4, AMIDE, 19, 1)
+    FIELD(AFMR4, AMIDL, 1, 18)
+    FIELD(AFMR4, AMRTR, 0, 1)
+REG32(AFIR4, 0x80)
+    FIELD(AFIR4, AIIDH, 21, 11)
+    FIELD(AFIR4, AISRR, 20, 1)
+    FIELD(AFIR4, AIIDE, 19, 1)
+    FIELD(AFIR4, AIIDL, 1, 18)
+    FIELD(AFIR4, AIRTR, 0, 1)
+
+static void can_update_irq(XlnxZynqMPCANState *s)
+{
+    uint32_t irq;
+
+    /* Watermark register interrupts. */
+    if ((fifo32_num_free(&s->tx_fifo) / CAN_FRAME_SIZE) >
+            ARRAY_FIELD_EX32(s->regs, WIR, EW)) {
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFWMEMP, 1);
+    }
+
+    if ((fifo32_num_used(&s->rx_fifo) / CAN_FRAME_SIZE) >
+            ARRAY_FIELD_EX32(s->regs, WIR, FW)) {
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXFWMFLL, 1);
+    }
+
+    /* RX Interrupts. */
+    if (fifo32_num_used(&s->rx_fifo) >= CAN_FRAME_SIZE) {
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXNEMP, 1);
+    }
+
+    /* TX interrupts. */
+    if (fifo32_is_empty(&s->tx_fifo)) {
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFEMP, 1);
+    }
+
+    if (fifo32_is_full(&s->tx_fifo)) {
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXFLL, 1);
+    }
+
+    if (fifo32_is_full(&s->txhpb_fifo)) {
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXBFLL, 1);
+    }
+
+    irq = s->regs[R_INTERRUPT_STATUS_REGISTER];
+    irq &= s->regs[R_INTERRUPT_ENABLE_REGISTER];
+
+    trace_xlnx_can_update_irq(s->regs[R_INTERRUPT_STATUS_REGISTER],
+                              s->regs[R_INTERRUPT_ENABLE_REGISTER], irq);
+    qemu_set_irq(s->irq, irq);
+}
+
+static void can_ier_post_write(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    can_update_irq(s);
+}
+
+static uint64_t can_icr_pre_write(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    s->regs[R_INTERRUPT_STATUS_REGISTER] &= ~val;
+    can_update_irq(s);
+
+    return 0;
+}
+
+static void can_config_reset(XlnxZynqMPCANState *s)
+{
+    /* Reset all the configuration registers. */
+    register_reset(&s->reg_info[R_SOFTWARE_RESET_REGISTER]);
+    register_reset(&s->reg_info[R_MODE_SELECT_REGISTER]);
+    register_reset(
+              &s->reg_info[R_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER]);
+    register_reset(&s->reg_info[R_ARBITRATION_PHASE_BIT_TIMING_REGISTER]);
+    register_reset(&s->reg_info[R_STATUS_REGISTER]);
+    register_reset(&s->reg_info[R_INTERRUPT_STATUS_REGISTER]);
+    register_reset(&s->reg_info[R_INTERRUPT_ENABLE_REGISTER]);
+    register_reset(&s->reg_info[R_INTERRUPT_CLEAR_REGISTER]);
+    register_reset(&s->reg_info[R_WIR]);
+}
+
+static void can_config_mode(XlnxZynqMPCANState *s)
+{
+    register_reset(&s->reg_info[R_ERROR_COUNTER_REGISTER]);
+    register_reset(&s->reg_info[R_ERROR_STATUS_REGISTER]);
+
+    /* Put XlnxZynqMPCAN in configuration mode. */
+    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 1);
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, WKUP, 0);
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, SLP, 0);
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, BSOFF, 0);
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, ERROR, 0);
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 0);
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 0);
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 0);
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, ARBLST, 0);
+
+    can_update_irq(s);
+}
+
+static void update_status_register_mode_bits(XlnxZynqMPCANState *s)
+{
+    bool sleep_status = ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP);
+    bool sleep_mode = ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SLEEP);
+    /* Wake up interrupt bit. */
+    bool wakeup_irq_val = sleep_status && (sleep_mode == 0);
+    /* Sleep interrupt bit. */
+    bool sleep_irq_val = sleep_mode && (sleep_status == 0);
+
+    /* Clear previous core mode status bits. */
+    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, LBACK, 0);
+    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SLEEP, 0);
+    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SNOOP, 0);
+    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 0);
+
+    /* set current mode bit and generate irqs accordingly. */
+    if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, LBACK)) {
+        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, LBACK, 1);
+    } else if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SLEEP)) {
+        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SLEEP, 1);
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, SLP,
+                         sleep_irq_val);
+    } else if (ARRAY_FIELD_EX32(s->regs, MODE_SELECT_REGISTER, SNOOP)) {
+        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, SNOOP, 1);
+    } else {
+        /*
+         * If all bits are zero then XlnxZynqMPCAN is set in normal mode.
+         */
+        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, NORMAL, 1);
+        /* Set wakeup interrupt bit. */
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, WKUP,
+                         wakeup_irq_val);
+    }
+
+    can_update_irq(s);
+}
+
+static void can_exit_sleep_mode(XlnxZynqMPCANState *s)
+{
+    ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, 0);
+    update_status_register_mode_bits(s);
+}
+
+static void generate_frame(qemu_can_frame *frame, uint32_t *data)
+{
+    frame->can_id = data[0];
+    frame->can_dlc = FIELD_EX32(data[1], TXFIFO_DLC, DLC);
+
+    frame->data[0] = FIELD_EX32(data[2], TXFIFO_DATA1, DB3);
+    frame->data[1] = FIELD_EX32(data[2], TXFIFO_DATA1, DB2);
+    frame->data[2] = FIELD_EX32(data[2], TXFIFO_DATA1, DB1);
+    frame->data[3] = FIELD_EX32(data[2], TXFIFO_DATA1, DB0);
+
+    frame->data[4] = FIELD_EX32(data[3], TXFIFO_DATA2, DB7);
+    frame->data[5] = FIELD_EX32(data[3], TXFIFO_DATA2, DB6);
+    frame->data[6] = FIELD_EX32(data[3], TXFIFO_DATA2, DB5);
+    frame->data[7] = FIELD_EX32(data[3], TXFIFO_DATA2, DB4);
+}
+
+static bool tx_ready_check(XlnxZynqMPCANState *s)
+{
+    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to transfer data while"
+                      " data while controller is in reset mode.\n",
+                      path);
+        return false;
+    }
+
+    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to transfer"
+                      " data while controller is in configuration mode. Reset"
+                      " the core so operations can start fresh.\n",
+                      path);
+        return false;
+    }
+
+    if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to transfer"
+                      " data while controller is in SNOOP MODE.\n",
+                      path);
+        return false;
+    }
+
+    return true;
+}
+
+static void transfer_fifo(XlnxZynqMPCANState *s, Fifo32 *fifo)
+{
+    qemu_can_frame frame;
+    uint32_t data[CAN_FRAME_SIZE];
+    int i;
+    bool can_tx = tx_ready_check(s);
+
+    if (!can_tx) {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Controller is not enabled for data"
+                      " transfer.\n", path);
+        can_update_irq(s);
+        return;
+    }
+
+    while (!fifo32_is_empty(fifo)) {
+        for (i = 0; i < CAN_FRAME_SIZE; i++) {
+            data[i] = fifo32_pop(fifo);
+        }
+
+        if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, LBACK)) {
+            /*
+             * Controller is in loopback. In Loopback mode, the CAN core
+             * transmits a recessive bitstream on to the XlnxZynqMPCAN Bus.
+             * Any message transmitted is looped back to the RX line and
+             * acknowledged. The XlnxZynqMPCAN core receives any message
+             * that it transmits.
+             */
+            if (fifo32_is_full(&s->rx_fifo)) {
+                ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 1);
+            } else {
+                for (i = 0; i < CAN_FRAME_SIZE; i++) {
+                    fifo32_push(&s->rx_fifo, data[i]);
+                }
+
+                ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);
+            }
+        } else {
+            /* Normal mode Tx. */
+            generate_frame(&frame, data);
+
+            trace_xlnx_can_tx_data(frame.can_id, frame.can_dlc,
+                                   frame.data[0], frame.data[1],
+                                   frame.data[2], frame.data[3],
+                                   frame.data[4], frame.data[5],
+                                   frame.data[6], frame.data[7]);
+            can_bus_client_send(&s->bus_client, &frame, 1);
+        }
+    }
+
+    ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, TXOK, 1);
+    ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, TXBFLL, 0);
+
+    if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) {
+        can_exit_sleep_mode(s);
+    }
+
+    can_update_irq(s);
+}
+
+static uint64_t can_srr_pre_write(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    ARRAY_FIELD_DP32(s->regs, SOFTWARE_RESET_REGISTER, CEN,
+                     FIELD_EX32(val, SOFTWARE_RESET_REGISTER, CEN));
+
+    if (FIELD_EX32(val, SOFTWARE_RESET_REGISTER, SRST)) {
+        trace_xlnx_can_reset(val);
+
+        /* First, core will do software reset then will enter in config mode. */
+        can_config_reset(s);
+    }
+
+    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
+        can_config_mode(s);
+    } else {
+        /*
+         * Leave config mode. Now XlnxZynqMPCAN core will enter normal,
+         * sleep, snoop or loopback mode depending upon LBACK, SLEEP, SNOOP
+         * register states.
+         */
+        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, CONFIG, 0);
+
+        ptimer_transaction_begin(s->can_timer);
+        ptimer_set_count(s->can_timer, 0);
+        ptimer_transaction_commit(s->can_timer);
+
+        /* XlnxZynqMPCAN is out of config mode. It will send pending data. */
+        transfer_fifo(s, &s->txhpb_fifo);
+        transfer_fifo(s, &s->tx_fifo);
+    }
+
+    update_status_register_mode_bits(s);
+
+    return s->regs[R_SOFTWARE_RESET_REGISTER];
+}
+
+static uint64_t can_msr_pre_write(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+    uint8_t multi_mode;
+
+    /*
+     * Multiple mode set check. This is done to make sure user doesn't set
+     * multiple modes.
+     */
+    multi_mode = FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK) +
+                 FIELD_EX32(val, MODE_SELECT_REGISTER, SLEEP) +
+                 FIELD_EX32(val, MODE_SELECT_REGISTER, SNOOP);
+
+    if (multi_mode > 1) {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to config"
+                      " several modes simultaneously. One mode will be selected"
+                      " according to their priority: LBACK > SLEEP > SNOOP.\n",
+                      path);
+    }
+
+    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN) == 0) {
+        /* We are in configuration mode, any mode can be selected. */
+        s->regs[R_MODE_SELECT_REGISTER] = val;
+    } else {
+        bool sleep_mode_bit = FIELD_EX32(val, MODE_SELECT_REGISTER, SLEEP);
+
+        ARRAY_FIELD_DP32(s->regs, MODE_SELECT_REGISTER, SLEEP, sleep_mode_bit);
+
+        if (FIELD_EX32(val, MODE_SELECT_REGISTER, LBACK)) {
+            g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to set"
+                          " LBACK mode without setting CEN bit as 0.\n",
+                          path);
+        } else if (FIELD_EX32(val, MODE_SELECT_REGISTER, SNOOP)) {
+            g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: Attempting to set"
+                          " SNOOP mode without setting CEN bit as 0.\n",
+                          path);
+        }
+
+        update_status_register_mode_bits(s);
+    }
+
+    return s->regs[R_MODE_SELECT_REGISTER];
+}
+
+static uint64_t can_brpr_pre_write(RegisterInfo  *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    /* Only allow writes when in config mode. */
+    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
+        return s->regs[R_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER];
+    }
+
+    return val;
+}
+
+static uint64_t can_btr_pre_write(RegisterInfo  *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    /* Only allow writes when in config mode. */
+    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
+        return s->regs[R_ARBITRATION_PHASE_BIT_TIMING_REGISTER];
+    }
+
+    return val;
+}
+
+static uint64_t can_tcr_pre_write(RegisterInfo  *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    if (FIELD_EX32(val, TIMESTAMP_REGISTER, CTS)) {
+        ptimer_transaction_begin(s->can_timer);
+        ptimer_set_count(s->can_timer, 0);
+        ptimer_transaction_commit(s->can_timer);
+    }
+
+    return 0;
+}
+
+static void update_rx_fifo(XlnxZynqMPCANState *s, const qemu_can_frame *frame)
+{
+    bool filter_pass = false;
+    uint16_t timestamp = 0;
+
+    /* If no filter is enabled. Message will be stored in FIFO. */
+    if (!((ARRAY_FIELD_EX32(s->regs, AFR, UAF1)) |
+       (ARRAY_FIELD_EX32(s->regs, AFR, UAF2)) |
+       (ARRAY_FIELD_EX32(s->regs, AFR, UAF3)) |
+       (ARRAY_FIELD_EX32(s->regs, AFR, UAF4)))) {
+        filter_pass = true;
+    }
+
+    /*
+     * Messages that pass any of the acceptance filters will be stored in
+     * the RX FIFO.
+     */
+    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF1)) {
+        uint32_t id_masked = s->regs[R_AFMR1] & frame->can_id;
+        uint32_t filter_id_masked = s->regs[R_AFMR1] & s->regs[R_AFIR1];
+
+        if (filter_id_masked == id_masked) {
+            filter_pass = true;
+        }
+    }
+
+    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF2)) {
+        uint32_t id_masked = s->regs[R_AFMR2] & frame->can_id;
+        uint32_t filter_id_masked = s->regs[R_AFMR2] & s->regs[R_AFIR2];
+
+        if (filter_id_masked == id_masked) {
+            filter_pass = true;
+        }
+    }
+
+    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF3)) {
+        uint32_t id_masked = s->regs[R_AFMR3] & frame->can_id;
+        uint32_t filter_id_masked = s->regs[R_AFMR3] & s->regs[R_AFIR3];
+
+        if (filter_id_masked == id_masked) {
+            filter_pass = true;
+        }
+    }
+
+    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF4)) {
+        uint32_t id_masked = s->regs[R_AFMR4] & frame->can_id;
+        uint32_t filter_id_masked = s->regs[R_AFMR4] & s->regs[R_AFIR4];
+
+        if (filter_id_masked == id_masked) {
+            filter_pass = true;
+        }
+    }
+
+    if (!filter_pass) {
+        trace_xlnx_can_rx_fifo_filter_reject(frame->can_id, frame->can_dlc);
+        return;
+    }
+
+    /* Store the message in fifo if it passed through any of the filters. */
+    if (filter_pass && frame->can_dlc <= MAX_DLC) {
+
+        if (fifo32_is_full(&s->rx_fifo)) {
+            ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOFLW, 1);
+        } else {
+            timestamp = CAN_TIMER_MAX - ptimer_get_count(s->can_timer);
+
+            fifo32_push(&s->rx_fifo, frame->can_id);
+
+            fifo32_push(&s->rx_fifo, deposit32(0, R_RXFIFO_DLC_DLC_SHIFT,
+                                               R_RXFIFO_DLC_DLC_LENGTH,
+                                               frame->can_dlc) |
+                                     deposit32(0, R_RXFIFO_DLC_RXT_SHIFT,
+                                               R_RXFIFO_DLC_RXT_LENGTH,
+                                               timestamp));
+
+            /* First 32 bit of the data. */
+            fifo32_push(&s->rx_fifo, deposit32(0, R_TXFIFO_DATA1_DB3_SHIFT,
+                                               R_TXFIFO_DATA1_DB3_LENGTH,
+                                               frame->data[0]) |
+                                     deposit32(0, R_TXFIFO_DATA1_DB2_SHIFT,
+                                               R_TXFIFO_DATA1_DB2_LENGTH,
+                                               frame->data[1]) |
+                                     deposit32(0, R_TXFIFO_DATA1_DB1_SHIFT,
+                                               R_TXFIFO_DATA1_DB1_LENGTH,
+                                               frame->data[2]) |
+                                     deposit32(0, R_TXFIFO_DATA1_DB0_SHIFT,
+                                               R_TXFIFO_DATA1_DB0_LENGTH,
+                                               frame->data[3]));
+            /* Last 32 bit of the data. */
+            fifo32_push(&s->rx_fifo, deposit32(0, R_TXFIFO_DATA2_DB7_SHIFT,
+                                               R_TXFIFO_DATA2_DB7_LENGTH,
+                                               frame->data[4]) |
+                                     deposit32(0, R_TXFIFO_DATA2_DB6_SHIFT,
+                                               R_TXFIFO_DATA2_DB6_LENGTH,
+                                               frame->data[5]) |
+                                     deposit32(0, R_TXFIFO_DATA2_DB5_SHIFT,
+                                               R_TXFIFO_DATA2_DB5_LENGTH,
+                                               frame->data[6]) |
+                                     deposit32(0, R_TXFIFO_DATA2_DB4_SHIFT,
+                                               R_TXFIFO_DATA2_DB4_LENGTH,
+                                               frame->data[7]));
+
+            ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);
+            trace_xlnx_can_rx_data(frame->can_id, frame->can_dlc,
+                                   frame->data[0], frame->data[1],
+                                   frame->data[2], frame->data[3],
+                                   frame->data[4], frame->data[5],
+                                   frame->data[6], frame->data[7]);
+        }
+
+        can_update_irq(s);
+    }
+}
+
+static uint64_t can_rxfifo_pre_read(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    if (!fifo32_is_empty(&s->rx_fifo)) {
+        val = fifo32_pop(&s->rx_fifo);
+    } else {
+        ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXUFLW, 1);
+    }
+
+    can_update_irq(s);
+    return val;
+}
+
+static void can_filter_enable_post_write(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    if (ARRAY_FIELD_EX32(s->regs, AFR, UAF1) &&
+        ARRAY_FIELD_EX32(s->regs, AFR, UAF2) &&
+        ARRAY_FIELD_EX32(s->regs, AFR, UAF3) &&
+        ARRAY_FIELD_EX32(s->regs, AFR, UAF4)) {
+        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, ACFBSY, 1);
+    } else {
+        ARRAY_FIELD_DP32(s->regs, STATUS_REGISTER, ACFBSY, 0);
+    }
+}
+
+static uint64_t can_filter_mask_pre_write(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+    uint32_t reg_idx = (reg->access->addr) / 4;
+    uint32_t filter_number = (reg_idx - R_AFMR1) / 2;
+
+    /* modify an acceptance filter, the corresponding UAF bit should be '0'. */
+    if (!(s->regs[R_AFR] & (1 << filter_number))) {
+        s->regs[reg_idx] = val;
+
+        trace_xlnx_can_filter_mask_pre_write(filter_number, s->regs[reg_idx]);
+    } else {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Acceptance filter %d"
+                      " mask is not set as corresponding UAF bit is not 0.\n",
+                      path, filter_number + 1);
+    }
+
+    return s->regs[reg_idx];
+}
+
+static uint64_t can_filter_id_pre_write(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+    uint32_t reg_idx = (reg->access->addr) / 4;
+    uint32_t filter_number = (reg_idx - R_AFIR1) / 2;
+
+    if (!(s->regs[R_AFR] & (1 << filter_number))) {
+        s->regs[reg_idx] = val;
+
+        trace_xlnx_can_filter_id_pre_write(filter_number, s->regs[reg_idx]);
+    } else {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Acceptance filter %d"
+                      " id is not set as corresponding UAF bit is not 0.\n",
+                      path, filter_number + 1);
+    }
+
+    return s->regs[reg_idx];
+}
+
+static void can_tx_post_write(RegisterInfo *reg, uint64_t val)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(reg->opaque);
+
+    bool is_txhpb = reg->access->addr > A_TXFIFO_DATA2;
+
+    bool initiate_transfer = (reg->access->addr == A_TXFIFO_DATA2) ||
+                             (reg->access->addr == A_TXHPB_DATA2);
+
+    Fifo32 *f = is_txhpb ? &s->txhpb_fifo : &s->tx_fifo;
+
+    if (!fifo32_is_full(f)) {
+        fifo32_push(f, val);
+    } else {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: TX FIFO is full.\n", path);
+    }
+
+    /* Initiate the message send if TX register is written. */
+    if (initiate_transfer &&
+        ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) {
+        transfer_fifo(s, f);
+    }
+
+    can_update_irq(s);
+}
+
+static const RegisterAccessInfo can_regs_info[] = {
+    {   .name = "SOFTWARE_RESET_REGISTER",
+        .addr = A_SOFTWARE_RESET_REGISTER,
+        .rsvd = 0xfffffffc,
+        .pre_write = can_srr_pre_write,
+    },{ .name = "MODE_SELECT_REGISTER",
+        .addr = A_MODE_SELECT_REGISTER,
+        .rsvd = 0xfffffff8,
+        .pre_write = can_msr_pre_write,
+    },{ .name = "ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER",
+        .addr = A_ARBITRATION_PHASE_BAUD_RATE_PRESCALER_REGISTER,
+        .rsvd = 0xffffff00,
+        .pre_write = can_brpr_pre_write,
+    },{ .name = "ARBITRATION_PHASE_BIT_TIMING_REGISTER",
+        .addr = A_ARBITRATION_PHASE_BIT_TIMING_REGISTER,
+        .rsvd = 0xfffffe00,
+        .pre_write = can_btr_pre_write,
+    },{ .name = "ERROR_COUNTER_REGISTER",
+        .addr = A_ERROR_COUNTER_REGISTER,
+        .rsvd = 0xffff0000,
+        .ro = 0xffffffff,
+    },{ .name = "ERROR_STATUS_REGISTER",
+        .addr = A_ERROR_STATUS_REGISTER,
+        .rsvd = 0xffffffe0,
+        .w1c = 0x1f,
+    },{ .name = "STATUS_REGISTER",  .addr = A_STATUS_REGISTER,
+        .reset = 0x1,
+        .rsvd = 0xffffe000,
+        .ro = 0x1fff,
+    },{ .name = "INTERRUPT_STATUS_REGISTER",
+        .addr = A_INTERRUPT_STATUS_REGISTER,
+        .reset = 0x6000,
+        .rsvd = 0xffff8000,
+        .ro = 0x7fff,
+    },{ .name = "INTERRUPT_ENABLE_REGISTER",
+        .addr = A_INTERRUPT_ENABLE_REGISTER,
+        .rsvd = 0xffff8000,
+        .post_write = can_ier_post_write,
+    },{ .name = "INTERRUPT_CLEAR_REGISTER",
+        .addr = A_INTERRUPT_CLEAR_REGISTER,
+        .rsvd = 0xffff8000,
+        .pre_write = can_icr_pre_write,
+    },{ .name = "TIMESTAMP_REGISTER",
+        .addr = A_TIMESTAMP_REGISTER,
+        .rsvd = 0xfffffffe,
+        .pre_write = can_tcr_pre_write,
+    },{ .name = "WIR",  .addr = A_WIR,
+        .reset = 0x3f3f,
+        .rsvd = 0xffff0000,
+    },{ .name = "TXFIFO_ID",  .addr = A_TXFIFO_ID,
+        .post_write = can_tx_post_write,
+    },{ .name = "TXFIFO_DLC",  .addr = A_TXFIFO_DLC,
+        .rsvd = 0xfffffff,
+        .post_write = can_tx_post_write,
+    },{ .name = "TXFIFO_DATA1",  .addr = A_TXFIFO_DATA1,
+        .post_write = can_tx_post_write,
+    },{ .name = "TXFIFO_DATA2",  .addr = A_TXFIFO_DATA2,
+        .post_write = can_tx_post_write,
+    },{ .name = "TXHPB_ID",  .addr = A_TXHPB_ID,
+        .post_write = can_tx_post_write,
+    },{ .name = "TXHPB_DLC",  .addr = A_TXHPB_DLC,
+        .rsvd = 0xfffffff,
+        .post_write = can_tx_post_write,
+    },{ .name = "TXHPB_DATA1",  .addr = A_TXHPB_DATA1,
+        .post_write = can_tx_post_write,
+    },{ .name = "TXHPB_DATA2",  .addr = A_TXHPB_DATA2,
+        .post_write = can_tx_post_write,
+    },{ .name = "RXFIFO_ID",  .addr = A_RXFIFO_ID,
+        .ro = 0xffffffff,
+        .post_read = can_rxfifo_pre_read,
+    },{ .name = "RXFIFO_DLC",  .addr = A_RXFIFO_DLC,
+        .rsvd = 0xfff0000,
+        .post_read = can_rxfifo_pre_read,
+    },{ .name = "RXFIFO_DATA1",  .addr = A_RXFIFO_DATA1,
+        .post_read = can_rxfifo_pre_read,
+    },{ .name = "RXFIFO_DATA2",  .addr = A_RXFIFO_DATA2,
+        .post_read = can_rxfifo_pre_read,
+    },{ .name = "AFR",  .addr = A_AFR,
+        .rsvd = 0xfffffff0,
+        .post_write = can_filter_enable_post_write,
+    },{ .name = "AFMR1",  .addr = A_AFMR1,
+        .pre_write = can_filter_mask_pre_write,
+    },{ .name = "AFIR1",  .addr = A_AFIR1,
+        .pre_write = can_filter_id_pre_write,
+    },{ .name = "AFMR2",  .addr = A_AFMR2,
+        .pre_write = can_filter_mask_pre_write,
+    },{ .name = "AFIR2",  .addr = A_AFIR2,
+        .pre_write = can_filter_id_pre_write,
+    },{ .name = "AFMR3",  .addr = A_AFMR3,
+        .pre_write = can_filter_mask_pre_write,
+    },{ .name = "AFIR3",  .addr = A_AFIR3,
+        .pre_write = can_filter_id_pre_write,
+    },{ .name = "AFMR4",  .addr = A_AFMR4,
+        .pre_write = can_filter_mask_pre_write,
+    },{ .name = "AFIR4",  .addr = A_AFIR4,
+        .pre_write = can_filter_id_pre_write,
+    }
+};
+
+static void xlnx_zynqmp_can_ptimer_cb(void *opaque)
+{
+    /* No action required on the timer rollover. */
+}
+
+static const MemoryRegionOps can_ops = {
+    .read = register_read_memory,
+    .write = register_write_memory,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
+static void xlnx_zynqmp_can_reset_init(Object *obj, ResetType type)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
+    unsigned int i;
+
+    for (i = R_RXFIFO_ID; i < ARRAY_SIZE(s->reg_info); ++i) {
+        register_reset(&s->reg_info[i]);
+    }
+
+    ptimer_transaction_begin(s->can_timer);
+    ptimer_set_count(s->can_timer, 0);
+    ptimer_transaction_commit(s->can_timer);
+}
+
+static void xlnx_zynqmp_can_reset_hold(Object *obj)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
+    unsigned int i;
+
+    for (i = 0; i < R_RXFIFO_ID; ++i) {
+        register_reset(&s->reg_info[i]);
+    }
+
+    /*
+     * Reset FIFOs when CAN model is reset. This will clear the fifo writes
+     * done by post_write which gets called from register_reset function,
+     * post_write handle will not be able to trigger tx because CAN will be
+     * disabled when software_reset_register is cleared first.
+     */
+    fifo32_reset(&s->rx_fifo);
+    fifo32_reset(&s->tx_fifo);
+    fifo32_reset(&s->txhpb_fifo);
+}
+
+static bool xlnx_zynqmp_can_can_receive(CanBusClientState *client)
+{
+    XlnxZynqMPCANState *s = container_of(client, XlnxZynqMPCANState,
+                                         bus_client);
+
+    if (ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, SRST)) {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Controller is in reset state.\n",
+                      path);
+        return false;
+    }
+
+    if ((ARRAY_FIELD_EX32(s->regs, SOFTWARE_RESET_REGISTER, CEN)) == 0) {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Controller is disabled. Incoming"
+                      " messages will be discarded.\n", path);
+        return false;
+    }
+
+    return true;
+}
+
+static ssize_t xlnx_zynqmp_can_receive(CanBusClientState *client,
+                               const qemu_can_frame *buf, size_t buf_size) {
+    XlnxZynqMPCANState *s = container_of(client, XlnxZynqMPCANState,
+                                         bus_client);
+    const qemu_can_frame *frame = buf;
+
+    if (buf_size <= 0) {
+        g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Error in the data received.\n",
+                      path);
+        return 0;
+    }
+
+    if (ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SNOOP)) {
+        /* Snoop Mode: Just keep the data. no response back. */
+        update_rx_fifo(s, frame);
+    } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP))) {
+        /*
+         * XlnxZynqMPCAN is in sleep mode. Any data on bus will bring it to wake
+         * up state.
+         */
+        can_exit_sleep_mode(s);
+        update_rx_fifo(s, frame);
+    } else if ((ARRAY_FIELD_EX32(s->regs, STATUS_REGISTER, SLEEP)) == 0) {
+        update_rx_fifo(s, frame);
+    } else {
+        /*
+         * XlnxZynqMPCAN will not participate in normal bus communication
+         * and will not receive any messages transmitted by other CAN nodes.
+         */
+        trace_xlnx_can_rx_discard(s->regs[R_STATUS_REGISTER]);
+    }
+
+    return 1;
+}
+
+static CanBusClientInfo can_xilinx_bus_client_info = {
+    .can_receive = xlnx_zynqmp_can_can_receive,
+    .receive = xlnx_zynqmp_can_receive,
+};
+
+static int xlnx_zynqmp_can_connect_to_bus(XlnxZynqMPCANState *s,
+                                          CanBusState *bus)
+{
+    s->bus_client.info = &can_xilinx_bus_client_info;
+
+    if (can_bus_insert_client(bus, &s->bus_client) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void xlnx_zynqmp_can_realize(DeviceState *dev, Error **errp)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(dev);
+
+    if (s->canbus) {
+        if (xlnx_zynqmp_can_connect_to_bus(s, s->canbus) < 0) {
+            g_autofree char *path = object_get_canonical_path(OBJECT(s));
+
+            error_setg(errp, "%s: xlnx_zynqmp_can_connect_to_bus"
+                       " failed.", path);
+            return;
+        }
+    }
+
+    /* Create RX FIFO, TXFIFO, TXHPB storage. */
+    fifo32_create(&s->rx_fifo, RXFIFO_SIZE);
+    fifo32_create(&s->tx_fifo, RXFIFO_SIZE);
+    fifo32_create(&s->txhpb_fifo, CAN_FRAME_SIZE);
+
+    /* Allocate a new timer. */
+    s->can_timer = ptimer_init(xlnx_zynqmp_can_ptimer_cb, s,
+                               PTIMER_POLICY_DEFAULT);
+
+    ptimer_transaction_begin(s->can_timer);
+
+    ptimer_set_freq(s->can_timer, s->cfg.ext_clk_freq);
+    ptimer_set_limit(s->can_timer, CAN_TIMER_MAX, 1);
+    ptimer_run(s->can_timer, 0);
+    ptimer_transaction_commit(s->can_timer);
+}
+
+static void xlnx_zynqmp_can_init(Object *obj)
+{
+    XlnxZynqMPCANState *s = XLNX_ZYNQMP_CAN(obj);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+    RegisterInfoArray *reg_array;
+
+    memory_region_init(&s->iomem, obj, TYPE_XLNX_ZYNQMP_CAN,
+                        XLNX_ZYNQMP_CAN_R_MAX * 4);
+    reg_array = register_init_block32(DEVICE(obj), can_regs_info,
+                               ARRAY_SIZE(can_regs_info),
+                               s->reg_info, s->regs,
+                               &can_ops,
+                               XLNX_ZYNQMP_CAN_ERR_DEBUG,
+                               XLNX_ZYNQMP_CAN_R_MAX * 4);
+
+    memory_region_add_subregion(&s->iomem, 0x00, &reg_array->mem);
+    sysbus_init_mmio(sbd, &s->iomem);
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+}
+
+static const VMStateDescription vmstate_can = {
+    .name = TYPE_XLNX_ZYNQMP_CAN,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_FIFO32(rx_fifo, XlnxZynqMPCANState),
+        VMSTATE_FIFO32(tx_fifo, XlnxZynqMPCANState),
+        VMSTATE_FIFO32(txhpb_fifo, XlnxZynqMPCANState),
+        VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPCANState, XLNX_ZYNQMP_CAN_R_MAX),
+        VMSTATE_PTIMER(can_timer, XlnxZynqMPCANState),
+        VMSTATE_END_OF_LIST(),
+    }
+};
+
+static Property xlnx_zynqmp_can_properties[] = {
+    DEFINE_PROP_UINT32("ext_clk_freq", XlnxZynqMPCANState, cfg.ext_clk_freq,
+                       CAN_DEFAULT_CLOCK),
+    DEFINE_PROP_LINK("canbus", XlnxZynqMPCANState, canbus, TYPE_CAN_BUS,
+                     CanBusState *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xlnx_zynqmp_can_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+    rc->phases.enter = xlnx_zynqmp_can_reset_init;
+    rc->phases.hold = xlnx_zynqmp_can_reset_hold;
+    dc->realize = xlnx_zynqmp_can_realize;
+    device_class_set_props(dc, xlnx_zynqmp_can_properties);
+    dc->vmsd = &vmstate_can;
+}
+
+static const TypeInfo can_info = {
+    .name          = TYPE_XLNX_ZYNQMP_CAN,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(XlnxZynqMPCANState),
+    .class_init    = xlnx_zynqmp_can_class_init,
+    .instance_init = xlnx_zynqmp_can_init,
+};
+
+static void can_register_types(void)
+{
+    type_register_static(&can_info);
+}
+
+type_init(can_register_types)
diff --git a/hw/Kconfig b/hw/Kconfig
index 4de1797ffda..5ad3c6b5a4b 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -80,3 +80,4 @@ config XILINX_AXI
 config XLNX_ZYNQMP
     bool
     select REGISTER
+    select CAN_BUS
diff --git a/hw/net/can/meson.build b/hw/net/can/meson.build
index 714951f375a..8fabbd9ee68 100644
--- a/hw/net/can/meson.build
+++ b/hw/net/can/meson.build
@@ -4,3 +4,4 @@ softmmu_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_pcm3680_pci.c'))
 softmmu_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_mioe3680_pci.c'))
 softmmu_ss.add(when: 'CONFIG_CAN_CTUCANFD', if_true: files('ctucan_core.c'))
 softmmu_ss.add(when: 'CONFIG_CAN_CTUCANFD_PCI', if_true: files('ctucan_pci.c'))
+softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-can.c'))
diff --git a/hw/net/can/trace-events b/hw/net/can/trace-events
new file mode 100644
index 00000000000..8346a98ab5d
--- /dev/null
+++ b/hw/net/can/trace-events
@@ -0,0 +1,9 @@
+# xlnx-zynqmp-can.c
+xlnx_can_update_irq(uint32_t isr, uint32_t ier, uint32_t irq) "ISR: 0x%08x IER: 0x%08x IRQ: 0x%08x"
+xlnx_can_reset(uint32_t val) "Resetting controller with value = 0x%08x"
+xlnx_can_rx_fifo_filter_reject(uint32_t id, uint8_t dlc) "Frame: ID: 0x%08x DLC: 0x%02x"
+xlnx_can_filter_id_pre_write(uint8_t filter_num, uint32_t value) "Filter%d ID: 0x%08x"
+xlnx_can_filter_mask_pre_write(uint8_t filter_num, uint32_t value) "Filter%d MASK: 0x%08x"
+xlnx_can_tx_data(uint32_t id, uint8_t dlc, uint8_t db0, uint8_t db1, uint8_t db2, uint8_t db3, uint8_t db4, uint8_t db5, uint8_t db6, uint8_t db7) "Frame: ID: 0x%08x DLC: 0x%02x DATA: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x"
+xlnx_can_rx_data(uint32_t id, uint32_t dlc, uint8_t db0, uint8_t db1, uint8_t db2, uint8_t db3, uint8_t db4, uint8_t db5, uint8_t db6, uint8_t db7) "Frame: ID: 0x%08x DLC: 0x%02x DATA: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x"
+xlnx_can_rx_discard(uint32_t status) "Controller is not enabled for bus communication. Status Register: 0x%08x"
-- 
2.20.1



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

* [PULL 03/36] xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
  2020-12-10 11:47 ` [PULL 01/36] hw/arm/smmuv3: Fix up L1STD_SPAN decoding Peter Maydell
  2020-12-10 11:47 ` [PULL 02/36] hw/net/can: Introduce Xilinx ZynqMP CAN controller Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 04/36] tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller Peter Maydell
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Vikram Garhwal <fnu.vikram@xilinx.com>

Connect CAN0 and CAN1 on the ZynqMP.

Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
Message-id: 1605728926-352690-3-git-send-email-fnu.vikram@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/xlnx-zynqmp.h |  8 ++++++++
 hw/arm/xlnx-zcu102.c         | 20 ++++++++++++++++++++
 hw/arm/xlnx-zynqmp.c         | 34 ++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+)

diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 567d0dba09b..6f45387a173 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -22,6 +22,7 @@
 #include "hw/intc/arm_gic.h"
 #include "hw/net/cadence_gem.h"
 #include "hw/char/cadence_uart.h"
+#include "hw/net/xlnx-zynqmp-can.h"
 #include "hw/ide/ahci.h"
 #include "hw/sd/sdhci.h"
 #include "hw/ssi/xilinx_spips.h"
@@ -33,6 +34,7 @@
 #include "hw/cpu/cluster.h"
 #include "target/arm/cpu.h"
 #include "qom/object.h"
+#include "net/can_emu.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
 OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
@@ -41,6 +43,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
 #define XLNX_ZYNQMP_NUM_RPU_CPUS 2
 #define XLNX_ZYNQMP_NUM_GEMS 4
 #define XLNX_ZYNQMP_NUM_UARTS 2
+#define XLNX_ZYNQMP_NUM_CAN 2
+#define XLNX_ZYNQMP_CAN_REF_CLK (24 * 1000 * 1000)
 #define XLNX_ZYNQMP_NUM_SDHCI 2
 #define XLNX_ZYNQMP_NUM_SPIS 2
 #define XLNX_ZYNQMP_NUM_GDMA_CH 8
@@ -92,6 +96,7 @@ struct XlnxZynqMPState {
 
     CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
     CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
+    XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN];
     SysbusAHCIState sata;
     SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
     XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
@@ -112,6 +117,9 @@ struct XlnxZynqMPState {
     bool virt;
     /* Has the RPU subsystem?  */
     bool has_rpu;
+
+    /* CAN bus. */
+    CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
 };
 
 #endif
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
index ad7fff9697b..4ef0c516bfd 100644
--- a/hw/arm/xlnx-zcu102.c
+++ b/hw/arm/xlnx-zcu102.c
@@ -25,6 +25,7 @@
 #include "sysemu/qtest.h"
 #include "sysemu/device_tree.h"
 #include "qom/object.h"
+#include "net/can_emu.h"
 
 struct XlnxZCU102 {
     MachineState parent_obj;
@@ -34,6 +35,8 @@ struct XlnxZCU102 {
     bool secure;
     bool virt;
 
+    CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
+
     struct arm_boot_info binfo;
 };
 
@@ -125,6 +128,14 @@ static void xlnx_zcu102_init(MachineState *machine)
     object_property_set_bool(OBJECT(&s->soc), "virtualization", s->virt,
                              &error_fatal);
 
+    for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+        gchar *bus_name = g_strdup_printf("canbus%d", i);
+
+        object_property_set_link(OBJECT(&s->soc), bus_name,
+                                 OBJECT(s->canbus[i]), &error_fatal);
+        g_free(bus_name);
+    }
+
     qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
 
     /* Create and plug in the SD cards */
@@ -208,6 +219,15 @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
     s->secure = false;
     /* Default to virt (EL2) being disabled */
     s->virt = false;
+    object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
+                             (Object **)&s->canbus[0],
+                             object_property_allow_set_link,
+                             0);
+
+    object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
+                             (Object **)&s->canbus[1],
+                             object_property_allow_set_link,
+                             0);
 }
 
 static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 7885bb17745..881847255b4 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -81,6 +81,14 @@ static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
     21, 22,
 };
 
+static const uint64_t can_addr[XLNX_ZYNQMP_NUM_CAN] = {
+    0xFF060000, 0xFF070000,
+};
+
+static const int can_intr[XLNX_ZYNQMP_NUM_CAN] = {
+    23, 24,
+};
+
 static const uint64_t sdhci_addr[XLNX_ZYNQMP_NUM_SDHCI] = {
     0xFF160000, 0xFF170000,
 };
@@ -243,6 +251,11 @@ static void xlnx_zynqmp_init(Object *obj)
                                 TYPE_CADENCE_UART);
     }
 
+    for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+        object_initialize_child(obj, "can[*]", &s->can[i],
+                                TYPE_XLNX_ZYNQMP_CAN);
+    }
+
     object_initialize_child(obj, "sata", &s->sata, TYPE_SYSBUS_AHCI);
 
     for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
@@ -482,6 +495,23 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
                            gic_spi[uart_intr[i]]);
     }
 
+    for (i = 0; i < XLNX_ZYNQMP_NUM_CAN; i++) {
+        object_property_set_int(OBJECT(&s->can[i]), "ext_clk_freq",
+                                XLNX_ZYNQMP_CAN_REF_CLK, &error_abort);
+
+        object_property_set_link(OBJECT(&s->can[i]), "canbus",
+                                 OBJECT(s->canbus[i]), &error_fatal);
+
+        sysbus_realize(SYS_BUS_DEVICE(&s->can[i]), &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->can[i]), 0, can_addr[i]);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->can[i]), 0,
+                           gic_spi[can_intr[i]]);
+    }
+
     object_property_set_int(OBJECT(&s->sata), "num-ports", SATA_NUM_PORTS,
                             &error_abort);
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->sata), errp)) {
@@ -619,6 +649,10 @@ static Property xlnx_zynqmp_props[] = {
     DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
     DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
                      MemoryRegion *),
+    DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
+                     CanBusState *),
+    DEFINE_PROP_LINK("canbus1", XlnxZynqMPState, canbus[1], TYPE_CAN_BUS,
+                     CanBusState *),
     DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.20.1



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

* [PULL 04/36] tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (2 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 03/36] xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 05/36] MAINTAINERS: Add maintainer entry " Peter Maydell
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Vikram Garhwal <fnu.vikram@xilinx.com>

The QTests perform five tests on the Xilinx ZynqMP CAN controller:
    Tests the CAN controller in loopback, sleep and snoop mode.
    Tests filtering of incoming CAN messages.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
Message-id: 1605728926-352690-4-git-send-email-fnu.vikram@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/qtest/xlnx-can-test.c | 360 ++++++++++++++++++++++++++++++++++++
 tests/qtest/meson.build     |   1 +
 2 files changed, 361 insertions(+)
 create mode 100644 tests/qtest/xlnx-can-test.c

diff --git a/tests/qtest/xlnx-can-test.c b/tests/qtest/xlnx-can-test.c
new file mode 100644
index 00000000000..3d1120005b6
--- /dev/null
+++ b/tests/qtest/xlnx-can-test.c
@@ -0,0 +1,360 @@
+/*
+ * QTests for the Xilinx ZynqMP CAN controller.
+ *
+ * Copyright (c) 2020 Xilinx Inc.
+ *
+ * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "libqos/libqtest.h"
+
+/* Base address. */
+#define CAN0_BASE_ADDR          0xFF060000
+#define CAN1_BASE_ADDR          0xFF070000
+
+/* Register addresses. */
+#define R_SRR_OFFSET            0x00
+#define R_MSR_OFFSET            0x04
+#define R_SR_OFFSET             0x18
+#define R_ISR_OFFSET            0x1C
+#define R_ICR_OFFSET            0x24
+#define R_TXID_OFFSET           0x30
+#define R_TXDLC_OFFSET          0x34
+#define R_TXDATA1_OFFSET        0x38
+#define R_TXDATA2_OFFSET        0x3C
+#define R_RXID_OFFSET           0x50
+#define R_RXDLC_OFFSET          0x54
+#define R_RXDATA1_OFFSET        0x58
+#define R_RXDATA2_OFFSET        0x5C
+#define R_AFR                   0x60
+#define R_AFMR1                 0x64
+#define R_AFIR1                 0x68
+#define R_AFMR2                 0x6C
+#define R_AFIR2                 0x70
+#define R_AFMR3                 0x74
+#define R_AFIR3                 0x78
+#define R_AFMR4                 0x7C
+#define R_AFIR4                 0x80
+
+/* CAN modes. */
+#define CONFIG_MODE             0x00
+#define NORMAL_MODE             0x00
+#define LOOPBACK_MODE           0x02
+#define SNOOP_MODE              0x04
+#define SLEEP_MODE              0x01
+#define ENABLE_CAN              (1 << 1)
+#define STATUS_NORMAL_MODE      (1 << 3)
+#define STATUS_LOOPBACK_MODE    (1 << 1)
+#define STATUS_SNOOP_MODE       (1 << 12)
+#define STATUS_SLEEP_MODE       (1 << 2)
+#define ISR_TXOK                (1 << 1)
+#define ISR_RXOK                (1 << 4)
+
+static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
+                             uint8_t can_timestamp)
+{
+    uint16_t size = 0;
+    uint8_t len = 4;
+
+    while (size < len) {
+        if (R_RXID_OFFSET + 4 * size == R_RXDLC_OFFSET)  {
+            g_assert_cmpint(buf_rx[size], ==, buf_tx[size] + can_timestamp);
+        } else {
+            g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
+        }
+
+        size++;
+    }
+}
+
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
+{
+    uint32_t int_status;
+
+    /* Read the interrupt on CAN rx. */
+    int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
+
+    g_assert_cmpint(int_status, ==, ISR_RXOK);
+
+    /* Read the RX register data for CAN. */
+    buf_rx[0] = qtest_readl(qts, can_base_addr + R_RXID_OFFSET);
+    buf_rx[1] = qtest_readl(qts, can_base_addr + R_RXDLC_OFFSET);
+    buf_rx[2] = qtest_readl(qts, can_base_addr + R_RXDATA1_OFFSET);
+    buf_rx[3] = qtest_readl(qts, can_base_addr + R_RXDATA2_OFFSET);
+
+    /* Clear the RX interrupt. */
+    qtest_writel(qts, CAN1_BASE_ADDR + R_ICR_OFFSET, ISR_RXOK);
+}
+
+static void send_data(QTestState *qts, uint64_t can_base_addr,
+                      const uint32_t *buf_tx)
+{
+    uint32_t int_status;
+
+    /* Write the TX register data for CAN. */
+    qtest_writel(qts, can_base_addr + R_TXID_OFFSET, buf_tx[0]);
+    qtest_writel(qts, can_base_addr + R_TXDLC_OFFSET, buf_tx[1]);
+    qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET, buf_tx[2]);
+    qtest_writel(qts, can_base_addr + R_TXDATA2_OFFSET, buf_tx[3]);
+
+    /* Read the interrupt on CAN for tx. */
+    int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_TXOK;
+
+    g_assert_cmpint(int_status, ==, ISR_TXOK);
+
+    /* Clear the interrupt for tx. */
+    qtest_writel(qts, CAN0_BASE_ADDR + R_ICR_OFFSET, ISR_TXOK);
+}
+
+/*
+ * This test will be transferring data from CAN0 and CAN1 through canbus. CAN0
+ * initiate the data transfer to can-bus, CAN1 receives the data. Test compares
+ * the data sent from CAN0 with received on CAN1.
+ */
+static void test_can_bus(void)
+{
+    const uint32_t buf_tx[4] = { 0xFF, 0x80000000, 0x12345678, 0x87654321 };
+    uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
+    uint32_t status = 0;
+    uint8_t can_timestamp = 1;
+
+    QTestState *qts = qtest_init("-machine xlnx-zcu102"
+                " -object can-bus,id=canbus0"
+                " -machine xlnx-zcu102.canbus0=canbus0"
+                " -machine xlnx-zcu102.canbus1=canbus0"
+                );
+
+    /* Configure the CAN0 and CAN1. */
+    qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+    qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
+
+    /* Check here if CAN0 and CAN1 are in normal mode. */
+    status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+    status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+    send_data(qts, CAN0_BASE_ADDR, buf_tx);
+
+    read_data(qts, CAN1_BASE_ADDR, buf_rx);
+    match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
+
+    qtest_quit(qts);
+}
+
+/*
+ * This test is performing loopback mode on CAN0 and CAN1. Data sent from TX of
+ * each CAN0 and CAN1 are compared with RX register data for respective CAN.
+ */
+static void test_can_loopback(void)
+{
+    uint32_t buf_tx[4] = { 0xFF, 0x80000000, 0x12345678, 0x87654321 };
+    uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
+    uint32_t status = 0;
+
+    QTestState *qts = qtest_init("-machine xlnx-zcu102"
+                " -object can-bus,id=canbus0"
+                " -machine xlnx-zcu102.canbus0=canbus0"
+                " -machine xlnx-zcu102.canbus1=canbus0"
+                );
+
+    /* Configure the CAN0 in loopback mode. */
+    qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
+    qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, LOOPBACK_MODE);
+    qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+
+    /* Check here if CAN0 is set in loopback mode. */
+    status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
+
+    g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
+
+    send_data(qts, CAN0_BASE_ADDR, buf_tx);
+    read_data(qts, CAN0_BASE_ADDR, buf_rx);
+    match_rx_tx_data(buf_tx, buf_rx, 0);
+
+    /* Configure the CAN1 in loopback mode. */
+    qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, LOOPBACK_MODE);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+
+    /* Check here if CAN1 is set in loopback mode. */
+    status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
+
+    g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
+
+    send_data(qts, CAN1_BASE_ADDR, buf_tx);
+    read_data(qts, CAN1_BASE_ADDR, buf_rx);
+    match_rx_tx_data(buf_tx, buf_rx, 0);
+
+    qtest_quit(qts);
+}
+
+/*
+ * Enable filters for CAN1. This will filter incoming messages with ID. In this
+ * test message will pass through filter 2.
+ */
+static void test_can_filter(void)
+{
+    uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
+    uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
+    uint32_t status = 0;
+    uint8_t can_timestamp = 1;
+
+    QTestState *qts = qtest_init("-machine xlnx-zcu102"
+                " -object can-bus,id=canbus0"
+                " -machine xlnx-zcu102.canbus0=canbus0"
+                " -machine xlnx-zcu102.canbus1=canbus0"
+                );
+
+    /* Configure the CAN0 and CAN1. */
+    qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+    qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
+
+    /* Check here if CAN0 and CAN1 are in normal mode. */
+    status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+    status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+    /* Set filter for CAN1 for incoming messages. */
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFR, 0x0);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR1, 0xF7);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR1, 0x121F);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR2, 0x5431);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR2, 0x14);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR3, 0x1234);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR3, 0x5431);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR4, 0xFFF);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR4, 0x1234);
+
+    qtest_writel(qts, CAN1_BASE_ADDR + R_AFR, 0xF);
+
+    send_data(qts, CAN0_BASE_ADDR, buf_tx);
+
+    read_data(qts, CAN1_BASE_ADDR, buf_rx);
+    match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
+
+    qtest_quit(qts);
+}
+
+/* Testing sleep mode on CAN0 while CAN1 is in normal mode. */
+static void test_can_sleepmode(void)
+{
+    uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
+    uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
+    uint32_t status = 0;
+    uint8_t can_timestamp = 1;
+
+    QTestState *qts = qtest_init("-machine xlnx-zcu102"
+                " -object can-bus,id=canbus0"
+                " -machine xlnx-zcu102.canbus0=canbus0"
+                " -machine xlnx-zcu102.canbus1=canbus0"
+                );
+
+    /* Configure the CAN0. */
+    qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
+    qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, SLEEP_MODE);
+    qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+
+    qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
+
+    /* Check here if CAN0 is in SLEEP mode and CAN1 in normal mode. */
+    status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_SLEEP_MODE);
+
+    status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+    send_data(qts, CAN1_BASE_ADDR, buf_tx);
+
+    /*
+     * Once CAN1 sends data on can-bus. CAN0 should exit sleep mode.
+     * Check the CAN0 status now. It should exit the sleep mode and receive the
+     * incoming data.
+     */
+    status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+    read_data(qts, CAN0_BASE_ADDR, buf_rx);
+
+    match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
+
+    qtest_quit(qts);
+}
+
+/* Testing Snoop mode on CAN0 while CAN1 is in normal mode. */
+static void test_can_snoopmode(void)
+{
+    uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
+    uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
+    uint32_t status = 0;
+    uint8_t can_timestamp = 1;
+
+    QTestState *qts = qtest_init("-machine xlnx-zcu102"
+                " -object can-bus,id=canbus0"
+                " -machine xlnx-zcu102.canbus0=canbus0"
+                " -machine xlnx-zcu102.canbus1=canbus0"
+                );
+
+    /* Configure the CAN0. */
+    qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
+    qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, SNOOP_MODE);
+    qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+
+    qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
+    qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
+
+    /* Check here if CAN0 is in SNOOP mode and CAN1 in normal mode. */
+    status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_SNOOP_MODE);
+
+    status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
+    g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+    send_data(qts, CAN1_BASE_ADDR, buf_tx);
+
+    read_data(qts, CAN0_BASE_ADDR, buf_rx);
+
+    match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
+
+    qtest_quit(qts);
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("/net/can/can_bus", test_can_bus);
+    qtest_add_func("/net/can/can_loopback", test_can_loopback);
+    qtest_add_func("/net/can/can_filter", test_can_filter);
+    qtest_add_func("/net/can/can_test_snoopmode", test_can_snoopmode);
+    qtest_add_func("/net/can/can_test_sleepmode", test_can_sleepmode);
+
+    return g_test_run();
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index c19f1c85034..4ca83ce6050 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -156,6 +156,7 @@ qtests_aarch64 = \
   ['arm-cpu-features',
    'numa-test',
    'boot-serial-test',
+   'xlnx-can-test',
    'migration-test']
 
 qtests_s390x = \
-- 
2.20.1



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

* [PULL 05/36] MAINTAINERS: Add maintainer entry for Xilinx ZynqMP CAN controller
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (3 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 04/36] tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 06/36] sbsa-ref: allow to use Cortex-A53/57/72 cpus Peter Maydell
                   ` (31 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Vikram Garhwal <fnu.vikram@xilinx.com>

Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
Message-id: 1605728926-352690-5-git-send-email-fnu.vikram@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 68bc160f41b..a83416d54c0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1563,6 +1563,14 @@ F: hw/net/opencores_eth.c
 
 Devices
 -------
+Xilinx CAN
+M: Vikram Garhwal <fnu.vikram@xilinx.com>
+M: Francisco Iglesias <francisco.iglesias@xilinx.com>
+S: Maintained
+F: hw/net/can/xlnx-*
+F: include/hw/net/xlnx-*
+F: tests/qtest/xlnx-can-test*
+
 EDU
 M: Jiri Slaby <jslaby@suse.cz>
 S: Maintained
-- 
2.20.1



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

* [PULL 06/36] sbsa-ref: allow to use Cortex-A53/57/72 cpus
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (4 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 05/36] MAINTAINERS: Add maintainer entry " Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 07/36] tests/qtest/npcm7xx_rng-test: dump random data on failure Peter Maydell
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>

Trusted Firmware now supports A72 on sbsa-ref by default [1] so enable
it for QEMU as well. A53 was already enabled there.

1. https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/7117

Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201120141705.246690-1-marcin.juszkiewicz@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/sbsa-ref.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 7d9e180c0db..4a5ea42938a 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -143,6 +143,24 @@ static const int sbsa_ref_irqmap[] = {
     [SBSA_GWDT] = 16,
 };
 
+static const char * const valid_cpus[] = {
+    ARM_CPU_TYPE_NAME("cortex-a53"),
+    ARM_CPU_TYPE_NAME("cortex-a57"),
+    ARM_CPU_TYPE_NAME("cortex-a72"),
+};
+
+static bool cpu_type_valid(const char *cpu)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(valid_cpus); i++) {
+        if (strcmp(cpu, valid_cpus[i]) == 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
 static uint64_t sbsa_ref_cpu_mp_affinity(SBSAMachineState *sms, int idx)
 {
     uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
@@ -649,9 +667,8 @@ static void sbsa_ref_init(MachineState *machine)
     const CPUArchIdList *possible_cpus;
     int n, sbsa_max_cpus;
 
-    if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
-        error_report("sbsa-ref: CPU type other than the built-in "
-                     "cortex-a57 not supported");
+    if (!cpu_type_valid(machine->cpu_type)) {
+        error_report("mach-virt: CPU type %s not supported", machine->cpu_type);
         exit(1);
     }
 
-- 
2.20.1



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

* [PULL 07/36] tests/qtest/npcm7xx_rng-test: dump random data on failure
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (5 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 06/36] sbsa-ref: allow to use Cortex-A53/57/72 cpus Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 08/36] i.MX25: Fix bad printf format specifiers Peter Maydell
                   ` (29 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Havard Skinnemoen <hskinnemoen@google.com>

Dump the collected random data after a randomness test failure.

Note that this relies on the test having called
g_test_set_nonfatal_assertions() so we don't abort immediately on the
assertion failure.

Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[PMM: minor commit message tweak]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 tests/qtest/npcm7xx_rng-test.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
index c614968ffcd..797f832e53a 100644
--- a/tests/qtest/npcm7xx_rng-test.c
+++ b/tests/qtest/npcm7xx_rng-test.c
@@ -20,6 +20,7 @@
 
 #include "libqtest-single.h"
 #include "qemu/bitops.h"
+#include "qemu-common.h"
 
 #define RNG_BASE_ADDR   0xf000b000
 
@@ -36,6 +37,13 @@
 /* Number of bits to collect for randomness tests. */
 #define TEST_INPUT_BITS  (128)
 
+static void dump_buf_if_failed(const uint8_t *buf, size_t size)
+{
+    if (g_test_failed()) {
+        qemu_hexdump(stderr, "", buf, size);
+    }
+}
+
 static void rng_writeb(unsigned int offset, uint8_t value)
 {
     writeb(RNG_BASE_ADDR + offset, value);
@@ -188,6 +196,7 @@ static void test_continuous_monobit(void)
     }
 
     g_assert_cmpfloat(calc_monobit_p(buf, sizeof(buf)), >, 0.01);
+    dump_buf_if_failed(buf, sizeof(buf));
 }
 
 /*
@@ -209,6 +218,7 @@ static void test_continuous_runs(void)
     }
 
     g_assert_cmpfloat(calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE), >, 0.01);
+    dump_buf_if_failed(buf.c, sizeof(buf));
 }
 
 /*
@@ -230,6 +240,7 @@ static void test_first_byte_monobit(void)
     }
 
     g_assert_cmpfloat(calc_monobit_p(buf, sizeof(buf)), >, 0.01);
+    dump_buf_if_failed(buf, sizeof(buf));
 }
 
 /*
@@ -254,6 +265,7 @@ static void test_first_byte_runs(void)
     }
 
     g_assert_cmpfloat(calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE), >, 0.01);
+    dump_buf_if_failed(buf.c, sizeof(buf));
 }
 
 int main(int argc, char **argv)
-- 
2.20.1



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

* [PULL 08/36] i.MX25: Fix bad printf format specifiers
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (6 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 07/36] tests/qtest/npcm7xx_rng-test: dump random data on failure Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 09/36] i.MX31: " Peter Maydell
                   ` (28 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Alex Chen <alex.chen@huawei.com>

We should use printf format specifier "%u" instead of "%d" for
argument of type "unsigned int".

Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
Message-id: 20201126111109.112238-2-alex.chen@huawei.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/imx25_ccm.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index d3107e5ca29..ff996e2f2ca 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -91,7 +91,7 @@ static const char *imx25_ccm_reg_name(uint32_t reg)
     case IMX25_CCM_LPIMR1_REG:
         return "lpimr1";
     default:
-        sprintf(unknown, "[%d ?]", reg);
+        sprintf(unknown, "[%u ?]", reg);
         return unknown;
     }
 }
@@ -118,7 +118,7 @@ static uint32_t imx25_ccm_get_mpll_clk(IMXCCMState *dev)
         freq = imx_ccm_calc_pll(s->reg[IMX25_CCM_MPCTL_REG], CKIH_FREQ);
     }
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -136,7 +136,7 @@ static uint32_t imx25_ccm_get_mcu_clk(IMXCCMState *dev)
 
     freq = freq / (1 + EXTRACT(s->reg[IMX25_CCM_CCTL_REG], ARM_CLK_DIV));
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -149,7 +149,7 @@ static uint32_t imx25_ccm_get_ahb_clk(IMXCCMState *dev)
     freq = imx25_ccm_get_mcu_clk(dev)
            / (1 + EXTRACT(s->reg[IMX25_CCM_CCTL_REG], AHB_CLK_DIV));
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -160,7 +160,7 @@ static uint32_t imx25_ccm_get_ipg_clk(IMXCCMState *dev)
 
     freq = imx25_ccm_get_ahb_clk(dev) / 2;
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -186,7 +186,7 @@ static uint32_t imx25_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
         break;
     }
 
-    DPRINTF("Clock = %d) = %d\n", clock, freq);
+    DPRINTF("Clock = %d) = %u\n", clock, freq);
 
     return freq;
 }
-- 
2.20.1



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

* [PULL 09/36] i.MX31: Fix bad printf format specifiers
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (7 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 08/36] i.MX25: Fix bad printf format specifiers Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 10/36] i.MX6: " Peter Maydell
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Alex Chen <alex.chen@huawei.com>

We should use printf format specifier "%u" instead of "%d" for
argument of type "unsigned int".

Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
Message-id: 20201126111109.112238-3-alex.chen@huawei.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/imx31_ccm.c | 14 +++++++-------
 hw/misc/imx_ccm.c   |  4 ++--
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 6e246827ab6..ad30a4b2c0c 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -89,7 +89,7 @@ static const char *imx31_ccm_reg_name(uint32_t reg)
     case IMX31_CCM_PDR2_REG:
         return "PDR2";
     default:
-        sprintf(unknown, "[%d ?]", reg);
+        sprintf(unknown, "[%u ?]", reg);
         return unknown;
     }
 }
@@ -120,7 +120,7 @@ static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState *dev)
         freq = CKIH_FREQ;
     }
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -133,7 +133,7 @@ static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev)
     freq = imx_ccm_calc_pll(s->reg[IMX31_CCM_MPCTL_REG],
                             imx31_ccm_get_pll_ref_clk(dev));
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -150,7 +150,7 @@ static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
         freq = imx31_ccm_get_mpll_clk(dev);
     }
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -163,7 +163,7 @@ static uint32_t imx31_ccm_get_hclk_clk(IMXCCMState *dev)
     freq = imx31_ccm_get_mcu_main_clk(dev)
            / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], MAX));
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -176,7 +176,7 @@ static uint32_t imx31_ccm_get_ipg_clk(IMXCCMState *dev)
     freq = imx31_ccm_get_hclk_clk(dev)
            / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG], IPG));
 
-    DPRINTF("freq = %d\n", freq);
+    DPRINTF("freq = %u\n", freq);
 
     return freq;
 }
@@ -201,7 +201,7 @@ static uint32_t imx31_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
         break;
     }
 
-    DPRINTF("Clock = %d) = %d\n", clock, freq);
+    DPRINTF("Clock = %d) = %u\n", clock, freq);
 
     return freq;
 }
diff --git a/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
index 52882071d3b..08a50ee4c8a 100644
--- a/hw/misc/imx_ccm.c
+++ b/hw/misc/imx_ccm.c
@@ -38,7 +38,7 @@ uint32_t imx_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
         freq = klass->get_clock_frequency(dev, clock);
     }
 
-    DPRINTF("(clock = %d) = %d\n", clock, freq);
+    DPRINTF("(clock = %d) = %u\n", clock, freq);
 
     return freq;
 }
@@ -65,7 +65,7 @@ uint32_t imx_ccm_calc_pll(uint32_t pllreg, uint32_t base_freq)
     freq = ((2 * (base_freq >> 10) * (mfi * mfd + mfn)) /
             (mfd * pd)) << 10;
 
-    DPRINTF("(pllreg = 0x%08x, base_freq = %d) = %d\n", pllreg, base_freq,
+    DPRINTF("(pllreg = 0x%08x, base_freq = %u) = %d\n", pllreg, base_freq,
             freq);
 
     return freq;
-- 
2.20.1



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

* [PULL 10/36] i.MX6: Fix bad printf format specifiers
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (8 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 09/36] i.MX31: " Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 11/36] i.MX6ul: " Peter Maydell
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Alex Chen <alex.chen@huawei.com>

We should use printf format specifier "%u" instead of "%d" for
argument of type "unsigned int".

Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
Message-id: 20201126111109.112238-4-alex.chen@huawei.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/imx6_ccm.c | 20 ++++++++++----------
 hw/misc/imx6_src.c |  2 +-
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
index 7fec8f0a476..cb740427eca 100644
--- a/hw/misc/imx6_ccm.c
+++ b/hw/misc/imx6_ccm.c
@@ -96,7 +96,7 @@ static const char *imx6_ccm_reg_name(uint32_t reg)
     case CCM_CMEOR:
         return "CMEOR";
     default:
-        sprintf(unknown, "%d ?", reg);
+        sprintf(unknown, "%u ?", reg);
         return unknown;
     }
 }
@@ -235,7 +235,7 @@ static const char *imx6_analog_reg_name(uint32_t reg)
     case USB_ANALOG_DIGPROG:
         return "USB_ANALOG_DIGPROG";
     default:
-        sprintf(unknown, "%d ?", reg);
+        sprintf(unknown, "%u ?", reg);
         return unknown;
     }
 }
@@ -263,7 +263,7 @@ static uint64_t imx6_analog_get_pll2_clk(IMX6CCMState *dev)
         freq *= 20;
     }
 
-    DPRINTF("freq = %d\n", (uint32_t)freq);
+    DPRINTF("freq = %u\n", (uint32_t)freq);
 
     return freq;
 }
@@ -275,7 +275,7 @@ static uint64_t imx6_analog_get_pll2_pfd0_clk(IMX6CCMState *dev)
     freq = imx6_analog_get_pll2_clk(dev) * 18
            / EXTRACT(dev->analog[CCM_ANALOG_PFD_528], PFD0_FRAC);
 
-    DPRINTF("freq = %d\n", (uint32_t)freq);
+    DPRINTF("freq = %u\n", (uint32_t)freq);
 
     return freq;
 }
@@ -287,7 +287,7 @@ static uint64_t imx6_analog_get_pll2_pfd2_clk(IMX6CCMState *dev)
     freq = imx6_analog_get_pll2_clk(dev) * 18
            / EXTRACT(dev->analog[CCM_ANALOG_PFD_528], PFD2_FRAC);
 
-    DPRINTF("freq = %d\n", (uint32_t)freq);
+    DPRINTF("freq = %u\n", (uint32_t)freq);
 
     return freq;
 }
@@ -315,7 +315,7 @@ static uint64_t imx6_analog_get_periph_clk(IMX6CCMState *dev)
         break;
     }
 
-    DPRINTF("freq = %d\n", (uint32_t)freq);
+    DPRINTF("freq = %u\n", (uint32_t)freq);
 
     return freq;
 }
@@ -327,7 +327,7 @@ static uint64_t imx6_ccm_get_ahb_clk(IMX6CCMState *dev)
     freq = imx6_analog_get_periph_clk(dev)
            / (1 + EXTRACT(dev->ccm[CCM_CBCDR], AHB_PODF));
 
-    DPRINTF("freq = %d\n", (uint32_t)freq);
+    DPRINTF("freq = %u\n", (uint32_t)freq);
 
     return freq;
 }
@@ -339,7 +339,7 @@ static uint64_t imx6_ccm_get_ipg_clk(IMX6CCMState *dev)
     freq = imx6_ccm_get_ahb_clk(dev)
            / (1 + EXTRACT(dev->ccm[CCM_CBCDR], IPG_PODF));
 
-    DPRINTF("freq = %d\n", (uint32_t)freq);
+    DPRINTF("freq = %u\n", (uint32_t)freq);
 
     return freq;
 }
@@ -351,7 +351,7 @@ static uint64_t imx6_ccm_get_per_clk(IMX6CCMState *dev)
     freq = imx6_ccm_get_ipg_clk(dev)
            / (1 + EXTRACT(dev->ccm[CCM_CSCMR1], PERCLK_PODF));
 
-    DPRINTF("freq = %d\n", (uint32_t)freq);
+    DPRINTF("freq = %u\n", (uint32_t)freq);
 
     return freq;
 }
@@ -385,7 +385,7 @@ static uint32_t imx6_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
         break;
     }
 
-    DPRINTF("Clock = %d) = %d\n", clock, freq);
+    DPRINTF("Clock = %d) = %u\n", clock, freq);
 
     return freq;
 }
diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c
index dd99cc7acf0..79f43759113 100644
--- a/hw/misc/imx6_src.c
+++ b/hw/misc/imx6_src.c
@@ -68,7 +68,7 @@ static const char *imx6_src_reg_name(uint32_t reg)
     case SRC_GPR10:
         return "SRC_GPR10";
     default:
-        sprintf(unknown, "%d ?", reg);
+        sprintf(unknown, "%u ?", reg);
         return unknown;
     }
 }
-- 
2.20.1



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

* [PULL 11/36] i.MX6ul: Fix bad printf format specifiers
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (9 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 10/36] i.MX6: " Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 12/36] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault Peter Maydell
                   ` (25 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

From: Alex Chen <alex.chen@huawei.com>

We should use printf format specifier "%u" instead of "%d" for
argument of type "unsigned int".

Reported-by: Euler Robot <euler.robot@huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
Message-id: 20201126111109.112238-5-alex.chen@huawei.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/misc/imx6ul_ccm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
index 5e0661dacf7..a65d0314556 100644
--- a/hw/misc/imx6ul_ccm.c
+++ b/hw/misc/imx6ul_ccm.c
@@ -143,7 +143,7 @@ static const char *imx6ul_ccm_reg_name(uint32_t reg)
     case CCM_CMEOR:
         return "CMEOR";
     default:
-        sprintf(unknown, "%d ?", reg);
+        sprintf(unknown, "%u ?", reg);
         return unknown;
     }
 }
@@ -274,7 +274,7 @@ static const char *imx6ul_analog_reg_name(uint32_t reg)
     case USB_ANALOG_DIGPROG:
         return "USB_ANALOG_DIGPROG";
     default:
-        sprintf(unknown, "%d ?", reg);
+        sprintf(unknown, "%u ?", reg);
         return unknown;
     }
 }
-- 
2.20.1



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

* [PULL 12/36] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (10 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 11/36] i.MX6ul: " Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 13/36] target/arm: Implement v8.1M PXN extension Peter Maydell
                   ` (24 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

For M-profile CPUs, the range from 0xe0000000 to 0xe00fffff is the
Private Peripheral Bus range, which includes all of the memory mapped
devices and registers that are part of the CPU itself, including the
NVIC, systick timer, and debug and trace components like the Data
Watchpoint and Trace unit (DWT).  Within this large region, the range
0xe000e000 to 0xe000efff is the System Control Space (NVIC, system
registers, systick) and 0xe002e000 to 0exe002efff is its Non-secure
alias.

The architecture is clear that within the SCS unimplemented registers
should be RES0 for privileged accesses and generate BusFault for
unprivileged accesses, and we currently implement this.

It is less clear about how to handle accesses to unimplemented
regions of the wider PPB.  Unprivileged accesses should definitely
cause BusFaults (R_DQQS), but the behaviour of privileged accesses is
not given as a general rule.  However, the register definitions of
individual registers for components like the DWT all state that they
are RES0 if the relevant component is not implemented, so the
simplest way to provide that is to provide RAZ/WI for the whole range
for privileged accesses.  (The v7M Arm ARM does say that reserved
registers should be UNK/SBZP.)

Expand the container MemoryRegion that the NVIC exposes so that
it covers the whole PPB space. This means:
 * moving the address that the ARMV7M device maps it to down by
   0xe000 bytes
 * moving the off and the offsets within the container of all the
   subregions forward by 0xe000 bytes
 * adding a new default MemoryRegion that covers the whole container
   at a lower priority than anything else and which provides the
   RAZWI/BusFault behaviour

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-2-peter.maydell@linaro.org
---
 include/hw/intc/armv7m_nvic.h |  1 +
 hw/arm/armv7m.c               |  2 +-
 hw/intc/armv7m_nvic.c         | 78 ++++++++++++++++++++++++++++++-----
 3 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index bb087b23c35..33b6d8810c7 100644
--- a/include/hw/intc/armv7m_nvic.h
+++ b/include/hw/intc/armv7m_nvic.h
@@ -84,6 +84,7 @@ struct NVICState {
     MemoryRegion systickmem;
     MemoryRegion systick_ns_mem;
     MemoryRegion container;
+    MemoryRegion defaultmem;
 
     uint32_t num_irq;
     qemu_irq excpout;
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 8113b29f1fd..944f261dd05 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -225,7 +225,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(sbd, 0,
                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
 
-    memory_region_add_subregion(&s->container, 0xe000e000,
+    memory_region_add_subregion(&s->container, 0xe0000000,
                                 sysbus_mmio_get_region(sbd, 0));
 
     for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 42b1ad59e65..9628ce876e0 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2479,6 +2479,43 @@ static const MemoryRegionOps nvic_systick_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+/*
+ * Unassigned portions of the PPB space are RAZ/WI for privileged
+ * accesses, and fault for non-privileged accesses.
+ */
+static MemTxResult ppb_default_read(void *opaque, hwaddr addr,
+                                    uint64_t *data, unsigned size,
+                                    MemTxAttrs attrs)
+{
+    qemu_log_mask(LOG_UNIMP, "Read of unassigned area of PPB: offset 0x%x\n",
+                  (uint32_t)addr);
+    if (attrs.user) {
+        return MEMTX_ERROR;
+    }
+    *data = 0;
+    return MEMTX_OK;
+}
+
+static MemTxResult ppb_default_write(void *opaque, hwaddr addr,
+                                     uint64_t value, unsigned size,
+                                     MemTxAttrs attrs)
+{
+    qemu_log_mask(LOG_UNIMP, "Write of unassigned area of PPB: offset 0x%x\n",
+                  (uint32_t)addr);
+    if (attrs.user) {
+        return MEMTX_ERROR;
+    }
+    return MEMTX_OK;
+}
+
+static const MemoryRegionOps ppb_default_ops = {
+    .read_with_attrs = ppb_default_read,
+    .write_with_attrs = ppb_default_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 8,
+};
+
 static int nvic_post_load(void *opaque, int version_id)
 {
     NVICState *s = opaque;
@@ -2675,7 +2712,6 @@ static void nvic_systick_trigger(void *opaque, int n, int level)
 static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
 {
     NVICState *s = NVIC(dev);
-    int regionlen;
 
     /* The armv7m container object will have set our CPU pointer */
     if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
@@ -2718,7 +2754,20 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
                                                   M_REG_S));
     }
 
-    /* The NVIC and System Control Space (SCS) starts at 0xe000e000
+    /*
+     * This device provides a single sysbus memory region which
+     * represents the whole of the "System PPB" space. This is the
+     * range from 0xe0000000 to 0xe00fffff and includes the NVIC,
+     * the System Control Space (system registers), the systick timer,
+     * and for CPUs with the Security extension an NS banked version
+     * of all of these.
+     *
+     * The default behaviour for unimplemented registers/ranges
+     * (for instance the Data Watchpoint and Trace unit at 0xe0001000)
+     * is to RAZ/WI for privileged access and BusFault for non-privileged
+     * access.
+     *
+     * The NVIC and System Control Space (SCS) starts at 0xe000e000
      * and looks like this:
      *  0x004 - ICTR
      *  0x010 - 0xff - systick
@@ -2741,32 +2790,39 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
      * generally code determining which banked register to use should
      * use attrs.secure; code determining actual behaviour of the system
      * should use env->v7m.secure.
+     *
+     * The container covers the whole PPB space. Within it the priority
+     * of overlapping regions is:
+     *  - default region (for RAZ/WI and BusFault) : -1
+     *  - system register regions : 0
+     *  - systick : 1
+     * This is because the systick device is a small block of registers
+     * in the middle of the other system control registers.
      */
-    regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
-    memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
-    /* The system register region goes at the bottom of the priority
-     * stack as it covers the whole page.
-     */
+    memory_region_init(&s->container, OBJECT(s), "nvic", 0x100000);
+    memory_region_init_io(&s->defaultmem, OBJECT(s), &ppb_default_ops, s,
+                          "nvic-default", 0x100000);
+    memory_region_add_subregion_overlap(&s->container, 0, &s->defaultmem, -1);
     memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
                           "nvic_sysregs", 0x1000);
-    memory_region_add_subregion(&s->container, 0, &s->sysregmem);
+    memory_region_add_subregion(&s->container, 0xe000, &s->sysregmem);
 
     memory_region_init_io(&s->systickmem, OBJECT(s),
                           &nvic_systick_ops, s,
                           "nvic_systick", 0xe0);
 
-    memory_region_add_subregion_overlap(&s->container, 0x10,
+    memory_region_add_subregion_overlap(&s->container, 0xe010,
                                         &s->systickmem, 1);
 
     if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
         memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
                               &nvic_sysreg_ns_ops, &s->sysregmem,
                               "nvic_sysregs_ns", 0x1000);
-        memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
+        memory_region_add_subregion(&s->container, 0x2e000, &s->sysreg_ns_mem);
         memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
                               &nvic_sysreg_ns_ops, &s->systickmem,
                               "nvic_systick_ns", 0xe0);
-        memory_region_add_subregion_overlap(&s->container, 0x20010,
+        memory_region_add_subregion_overlap(&s->container, 0x2e010,
                                             &s->systick_ns_mem, 1);
     }
 
-- 
2.20.1



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

* [PULL 13/36] target/arm: Implement v8.1M PXN extension
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (11 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 12/36] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 14/36] target/arm: Don't clobber ID_PFR1.Security on M-profile cores Peter Maydell
                   ` (23 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

In v8.1M the PXN architecture extension adds a new PXN bit to the
MPU_RLAR registers, which forbids execution of code in the region
from a privileged mode.

This is another feature which is just in the generic "in v8.1M" set
and has no ID register field indicating its presence.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-3-peter.maydell@linaro.org
---
 target/arm/helper.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 38cd35c0492..7b8bcd69030 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11754,6 +11754,11 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
     } else {
         uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
         uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
+        bool pxn = false;
+
+        if (arm_feature(env, ARM_FEATURE_V8_1M)) {
+            pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
+        }
 
         if (m_is_system_region(env, address)) {
             /* System space is always execute never */
@@ -11761,7 +11766,7 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
         }
 
         *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
-        if (*prot && !xn) {
+        if (*prot && !xn && !(pxn && !is_user)) {
             *prot |= PAGE_EXEC;
         }
         /* We don't need to look the attribute up in the MAIR0/MAIR1
-- 
2.20.1



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

* [PULL 14/36] target/arm: Don't clobber ID_PFR1.Security on M-profile cores
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (12 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 13/36] target/arm: Implement v8.1M PXN extension Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 15/36] target/arm: Implement VSCCLRM insn Peter Maydell
                   ` (22 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

In arm_cpu_realizefn() we check whether the board code disabled EL3
via the has_el3 CPU object property, which we create if the CPU
starts with the ARM_FEATURE_EL3 feature bit.  If it is disabled, then
we turn off ARM_FEATURE_EL3 and also zero out the relevant fields in
the ID_PFR1 and ID_AA64PFR0 registers.

This codepath was incorrectly being taken for M-profile CPUs, which
do not have an EL3 and don't set ARM_FEATURE_EL3, but which may have
the M-profile Security extension and so should have non-zero values
in the ID_PFR1.Security field.

Restrict the handling of the feature flag to A/R-profile cores.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-4-peter.maydell@linaro.org
---
 target/arm/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 07492e9f9a4..40f3f798b2b 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1674,7 +1674,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
         }
     }
 
-    if (!cpu->has_el3) {
+    if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3) {
         /* If the has_el3 CPU property is disabled then we need to disable the
          * feature.
          */
-- 
2.20.1



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

* [PULL 15/36] target/arm: Implement VSCCLRM insn
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (13 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 14/36] target/arm: Don't clobber ID_PFR1.Security on M-profile cores Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 16/36] target/arm: Implement CLRM instruction Peter Maydell
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

Implement the v8.1M VSCCLRM insn, which zeros floating point
registers if there is an active floating point context.
This requires support in write_neon_element32() for the MO_32
element size, so add it.

Because we want to use arm_gen_condlabel(), we need to move
the definition of that function up in translate.c so it is
before the #include of translate-vfp.c.inc.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-5-peter.maydell@linaro.org
---
 target/arm/cpu.h               |  9 ++++
 target/arm/m-nocp.decode       |  8 +++-
 target/arm/translate.c         | 21 +++++----
 target/arm/translate-vfp.c.inc | 84 ++++++++++++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e5514c82862..11400a9d248 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3555,6 +3555,15 @@ static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
     return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
 }
 
+static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
+{
+    /*
+     * Return true if M-profile state handling insns
+     * (VSCCLRM, CLRM, FPCTX access insns) are implemented
+     */
+    return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3;
+}
+
 static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
 {
     /* Sadly this is encoded differently for A-profile and M-profile */
diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
index 28c8ac6b94c..ccd62e8739a 100644
--- a/target/arm/m-nocp.decode
+++ b/target/arm/m-nocp.decode
@@ -29,13 +29,17 @@
 # If the coprocessor is not present or disabled then we will generate
 # the NOCP exception; otherwise we let the insn through to the main decode.
 
+%vd_dp  22:1 12:4
+%vd_sp  12:4 22:1
+
 &nocp cp
 
 {
   # Special cases which do not take an early NOCP: VLLDM and VLSTM
   VLLDM_VLSTM  1110 1100 001 l:1 rn:4 0000 1010 0000 0000
-  # TODO: VSCCLRM (new in v8.1M) is similar:
-  #VSCCLRM      1110 1100 1-01 1111 ---- 1011 ---- ---0
+  # VSCCLRM (new in v8.1M) is similar:
+  VSCCLRM      1110 1100 1.01 1111 .... 1011 imm:7 0   vd=%vd_dp size=3
+  VSCCLRM      1110 1100 1.01 1111 .... 1010 imm:8     vd=%vd_sp size=2
 
   NOCP         111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp
   NOCP         111- 110- ---- ---- ---- cp:4 ---- ---- &nocp
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 6d04ca3a8a0..9f2b6018a21 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -100,6 +100,15 @@ void arm_translate_init(void)
     a64_translate_init();
 }
 
+/* Generate a label used for skipping this instruction */
+static void arm_gen_condlabel(DisasContext *s)
+{
+    if (!s->condjmp) {
+        s->condlabel = gen_new_label();
+        s->condjmp = 1;
+    }
+}
+
 /* Flags for the disas_set_da_iss info argument:
  * lower bits hold the Rt register number, higher bits are flags.
  */
@@ -1221,6 +1230,9 @@ static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
     long off = neon_element_offset(reg, ele, memop);
 
     switch (memop) {
+    case MO_32:
+        tcg_gen_st32_i64(src, cpu_env, off);
+        break;
     case MO_64:
         tcg_gen_st_i64(src, cpu_env, off);
         break;
@@ -5156,15 +5168,6 @@ static void gen_srs(DisasContext *s,
     s->base.is_jmp = DISAS_UPDATE_EXIT;
 }
 
-/* Generate a label used for skipping this instruction */
-static void arm_gen_condlabel(DisasContext *s)
-{
-    if (!s->condjmp) {
-        s->condlabel = gen_new_label();
-        s->condjmp = 1;
-    }
-}
-
 /* Skip this instruction if the ARM condition is false */
 static void arm_skip_unless(DisasContext *s, uint32_t cond)
 {
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 96948f5a2d3..2a67ed0f6e2 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -3406,6 +3406,90 @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
     return true;
 }
 
+static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
+{
+    int btmreg, topreg;
+    TCGv_i64 zero;
+    TCGv_i32 aspen, sfpa;
+
+    if (!dc_isar_feature(aa32_m_sec_state, s)) {
+        /* Before v8.1M, fall through in decode to NOCP check */
+        return false;
+    }
+
+    /* Explicitly UNDEF because this takes precedence over NOCP */
+    if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
+        unallocated_encoding(s);
+        return true;
+    }
+
+    if (!dc_isar_feature(aa32_vfp_simd, s)) {
+        /* NOP if we have neither FP nor MVE */
+        return true;
+    }
+
+    /*
+     * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
+     * active floating point context so we must NOP (without doing
+     * any lazy state preservation or the NOCP check).
+     */
+    aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
+    sfpa = load_cpu_field(v7m.control[M_REG_S]);
+    tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
+    tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
+    tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
+    tcg_gen_or_i32(sfpa, sfpa, aspen);
+    arm_gen_condlabel(s);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
+
+    if (s->fp_excp_el != 0) {
+        gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
+                           syn_uncategorized(), s->fp_excp_el);
+        return true;
+    }
+
+    topreg = a->vd + a->imm - 1;
+    btmreg = a->vd;
+
+    /* Convert to Sreg numbers if the insn specified in Dregs */
+    if (a->size == 3) {
+        topreg = topreg * 2 + 1;
+        btmreg *= 2;
+    }
+
+    if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
+        /* UNPREDICTABLE: we choose to undef */
+        unallocated_encoding(s);
+        return true;
+    }
+
+    /* Silently ignore requests to clear D16-D31 if they don't exist */
+    if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
+        topreg = 31;
+    }
+
+    if (!vfp_access_check(s)) {
+        return true;
+    }
+
+    /* Zero the Sregs from btmreg to topreg inclusive. */
+    zero = tcg_const_i64(0);
+    if (btmreg & 1) {
+        write_neon_element64(zero, btmreg >> 1, 1, MO_32);
+        btmreg++;
+    }
+    for (; btmreg + 1 <= topreg; btmreg += 2) {
+        write_neon_element64(zero, btmreg >> 1, 0, MO_64);
+    }
+    if (btmreg == topreg) {
+        write_neon_element64(zero, btmreg >> 1, 0, MO_32);
+        btmreg++;
+    }
+    assert(btmreg == topreg + 1);
+    /* TODO: when MVE is implemented, zero VPR here */
+    return true;
+}
+
 static bool trans_NOCP(DisasContext *s, arg_nocp *a)
 {
     /*
-- 
2.20.1



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

* [PULL 16/36] target/arm: Implement CLRM instruction
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (14 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 15/36] target/arm: Implement VSCCLRM insn Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 17/36] target/arm: Enforce M-profile VMRS/VMSR register restrictions Peter Maydell
                   ` (20 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

In v8.1M the new CLRM instruction allows zeroing an arbitrary set of
the general-purpose registers and APSR.  Implement this.

The encoding is a subset of the LDMIA T2 encoding, using what would
be Rn=0b1111 (which UNDEFs for LDMIA).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-6-peter.maydell@linaro.org
---
 target/arm/t32.decode  |  6 +++++-
 target/arm/translate.c | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/arm/t32.decode b/target/arm/t32.decode
index cfcc71bfb0a..f045eb62c84 100644
--- a/target/arm/t32.decode
+++ b/target/arm/t32.decode
@@ -609,7 +609,11 @@ UXTAB            1111 1010 0101 .... 1111 .... 10.. ....      @rrr_rot
 
 STM_t32          1110 1000 10.0 .... ................         @ldstm i=1 b=0
 STM_t32          1110 1001 00.0 .... ................         @ldstm i=0 b=1
-LDM_t32          1110 1000 10.1 .... ................         @ldstm i=1 b=0
+{
+  # Rn=15 UNDEFs for LDM; M-profile CLRM uses that encoding
+  CLRM           1110 1000 1001 1111 list:16
+  LDM_t32        1110 1000 10.1 .... ................         @ldstm i=1 b=0
+}
 LDM_t32          1110 1001 00.1 .... ................         @ldstm i=0 b=1
 
 &rfe             !extern rn w pu
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 9f2b6018a21..47a1a5739c8 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -7968,6 +7968,44 @@ static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
     return do_ldm(s, a, 1);
 }
 
+static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
+{
+    int i;
+    TCGv_i32 zero;
+
+    if (!dc_isar_feature(aa32_m_sec_state, s)) {
+        return false;
+    }
+
+    if (extract32(a->list, 13, 1)) {
+        return false;
+    }
+
+    if (!a->list) {
+        /* UNPREDICTABLE; we choose to UNDEF */
+        return false;
+    }
+
+    zero = tcg_const_i32(0);
+    for (i = 0; i < 15; i++) {
+        if (extract32(a->list, i, 1)) {
+            /* Clear R[i] */
+            tcg_gen_mov_i32(cpu_R[i], zero);
+        }
+    }
+    if (extract32(a->list, 15, 1)) {
+        /*
+         * Clear APSR (by calling the MSR helper with the same argument
+         * as for "MSR APSR_nzcvqg, Rn": mask = 0b1100, SYSM=0)
+         */
+        TCGv_i32 maskreg = tcg_const_i32(0xc << 8);
+        gen_helper_v7m_msr(cpu_env, maskreg, zero);
+        tcg_temp_free_i32(maskreg);
+    }
+    tcg_temp_free_i32(zero);
+    return true;
+}
+
 /*
  * Branch, branch with link
  */
-- 
2.20.1



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

* [PULL 17/36] target/arm: Enforce M-profile VMRS/VMSR register restrictions
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (15 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 16/36] target/arm: Implement CLRM instruction Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 18/36] target/arm: Refactor M-profile VMSR/VMRS handling Peter Maydell
                   ` (19 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

For M-profile before v8.1M, the only valid register for VMSR/VMRS is
the FPSCR.  We have a comment that states this, but the actual logic
to forbid accesses for any other register value is missing, so we
would end up with A-profile style behaviour.  Add the missing check.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-7-peter.maydell@linaro.org
---
 target/arm/translate-vfp.c.inc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 2a67ed0f6e2..e100182a32c 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -622,7 +622,10 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
          * Accesses to R15 are UNPREDICTABLE; we choose to undef.
          * (FPSCR -> r15 is a special case which writes to the PSR flags.)
          */
-        if (a->rt == 15 && (!a->l || a->reg != ARM_VFP_FPSCR)) {
+        if (a->reg != ARM_VFP_FPSCR) {
+            return false;
+        }
+        if (a->rt == 15 && !a->l) {
             return false;
         }
     }
-- 
2.20.1



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

* [PULL 18/36] target/arm: Refactor M-profile VMSR/VMRS handling
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (16 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 17/36] target/arm: Enforce M-profile VMRS/VMSR register restrictions Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 19/36] target/arm: Move general-use constant expanders up in translate.c Peter Maydell
                   ` (18 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

Currently M-profile borrows the A-profile code for VMSR and VMRS
(access to the FP system registers), because all it needs to support
is the FPSCR.  In v8.1M things become significantly more complicated
in two ways:

 * there are several new FP system registers; some have side effects
   on read, and one (FPCXT_NS) needs to avoid the usual
   vfp_access_check() and the "only if FPU implemented" check

 * all sysregs are now accessible both by VMRS/VMSR (which
   reads/writes a general purpose register) and also by VLDR/VSTR
   (which reads/writes them directly to memory)

Refactor the structure of how we handle VMSR/VMRS to cope with this:

 * keep the M-profile code entirely separate from the A-profile code

 * abstract out the "read or write the general purpose register" part
   of the code into a loadfn or storefn function pointer, so we can
   reuse it for VLDR/VSTR.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-8-peter.maydell@linaro.org
---
 target/arm/cpu.h               |   3 +
 target/arm/translate-vfp.c.inc | 182 ++++++++++++++++++++++++++++++---
 2 files changed, 171 insertions(+), 14 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 11400a9d248..ad8b80c667d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1569,6 +1569,9 @@ enum arm_cpu_mode {
 #define ARM_VFP_FPINST  9
 #define ARM_VFP_FPINST2 10
 
+/* QEMU-internal value meaning "FPSCR, but we care only about NZCV" */
+#define QEMU_VFP_FPSCR_NZCV 0xffff
+
 /* iwMMXt coprocessor control registers.  */
 #define ARM_IWMMXT_wCID  0
 #define ARM_IWMMXT_wCon  1
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index e100182a32c..7a0cbca6640 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -607,27 +607,181 @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
     return true;
 }
 
+/*
+ * M-profile provides two different sets of instructions that can
+ * access floating point system registers: VMSR/VMRS (which move
+ * to/from a general purpose register) and VLDR/VSTR sysreg (which
+ * move directly to/from memory). In some cases there are also side
+ * effects which must happen after any write to memory (which could
+ * cause an exception). So we implement the common logic for the
+ * sysreg access in gen_M_fp_sysreg_write() and gen_M_fp_sysreg_read(),
+ * which take pointers to callback functions which will perform the
+ * actual "read/write general purpose register" and "read/write
+ * memory" operations.
+ */
+
+/*
+ * Emit code to store the sysreg to its final destination; frees the
+ * TCG temp 'value' it is passed.
+ */
+typedef void fp_sysreg_storefn(DisasContext *s, void *opaque, TCGv_i32 value);
+/*
+ * Emit code to load the value to be copied to the sysreg; returns
+ * a new TCG temporary
+ */
+typedef TCGv_i32 fp_sysreg_loadfn(DisasContext *s, void *opaque);
+
+/* Common decode/access checks for fp sysreg read/write */
+typedef enum FPSysRegCheckResult {
+    FPSysRegCheckFailed, /* caller should return false */
+    FPSysRegCheckDone, /* caller should return true */
+    FPSysRegCheckContinue, /* caller should continue generating code */
+} FPSysRegCheckResult;
+
+static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
+{
+    if (!dc_isar_feature(aa32_fpsp_v2, s)) {
+        return FPSysRegCheckFailed;
+    }
+
+    switch (regno) {
+    case ARM_VFP_FPSCR:
+    case QEMU_VFP_FPSCR_NZCV:
+        break;
+    default:
+        return FPSysRegCheckFailed;
+    }
+
+    if (!vfp_access_check(s)) {
+        return FPSysRegCheckDone;
+    }
+
+    return FPSysRegCheckContinue;
+}
+
+static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
+
+                                  fp_sysreg_loadfn *loadfn,
+                                 void *opaque)
+{
+    /* Do a write to an M-profile floating point system register */
+    TCGv_i32 tmp;
+
+    switch (fp_sysreg_checks(s, regno)) {
+    case FPSysRegCheckFailed:
+        return false;
+    case FPSysRegCheckDone:
+        return true;
+    case FPSysRegCheckContinue:
+        break;
+    }
+
+    switch (regno) {
+    case ARM_VFP_FPSCR:
+        tmp = loadfn(s, opaque);
+        gen_helper_vfp_set_fpscr(cpu_env, tmp);
+        tcg_temp_free_i32(tmp);
+        gen_lookup_tb(s);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    return true;
+}
+
+static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
+                                fp_sysreg_storefn *storefn,
+                                void *opaque)
+{
+    /* Do a read from an M-profile floating point system register */
+    TCGv_i32 tmp;
+
+    switch (fp_sysreg_checks(s, regno)) {
+    case FPSysRegCheckFailed:
+        return false;
+    case FPSysRegCheckDone:
+        return true;
+    case FPSysRegCheckContinue:
+        break;
+    }
+
+    switch (regno) {
+    case ARM_VFP_FPSCR:
+        tmp = tcg_temp_new_i32();
+        gen_helper_vfp_get_fpscr(tmp, cpu_env);
+        storefn(s, opaque, tmp);
+        break;
+    case QEMU_VFP_FPSCR_NZCV:
+        /*
+         * Read just NZCV; this is a special case to avoid the
+         * helper call for the "VMRS to CPSR.NZCV" insn.
+         */
+        tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
+        storefn(s, opaque, tmp);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    return true;
+}
+
+static void fp_sysreg_to_gpr(DisasContext *s, void *opaque, TCGv_i32 value)
+{
+    arg_VMSR_VMRS *a = opaque;
+
+    if (a->rt == 15) {
+        /* Set the 4 flag bits in the CPSR */
+        gen_set_nzcv(value);
+        tcg_temp_free_i32(value);
+    } else {
+        store_reg(s, a->rt, value);
+    }
+}
+
+static TCGv_i32 gpr_to_fp_sysreg(DisasContext *s, void *opaque)
+{
+    arg_VMSR_VMRS *a = opaque;
+
+    return load_reg(s, a->rt);
+}
+
+static bool gen_M_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
+{
+    /*
+     * Accesses to R15 are UNPREDICTABLE; we choose to undef.
+     * FPSCR -> r15 is a special case which writes to the PSR flags;
+     * set a->reg to a special value to tell gen_M_fp_sysreg_read()
+     * we only care about the top 4 bits of FPSCR there.
+     */
+    if (a->rt == 15) {
+        if (a->l && a->reg == ARM_VFP_FPSCR) {
+            a->reg = QEMU_VFP_FPSCR_NZCV;
+        } else {
+            return false;
+        }
+    }
+
+    if (a->l) {
+        /* VMRS, move FP system register to gp register */
+        return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_gpr, a);
+    } else {
+        /* VMSR, move gp register to FP system register */
+        return gen_M_fp_sysreg_write(s, a->reg, gpr_to_fp_sysreg, a);
+    }
+}
+
 static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
 {
     TCGv_i32 tmp;
     bool ignore_vfp_enabled = false;
 
-    if (!dc_isar_feature(aa32_fpsp_v2, s)) {
-        return false;
+    if (arm_dc_feature(s, ARM_FEATURE_M)) {
+        return gen_M_VMSR_VMRS(s, a);
     }
 
-    if (arm_dc_feature(s, ARM_FEATURE_M)) {
-        /*
-         * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
-         * Accesses to R15 are UNPREDICTABLE; we choose to undef.
-         * (FPSCR -> r15 is a special case which writes to the PSR flags.)
-         */
-        if (a->reg != ARM_VFP_FPSCR) {
-            return false;
-        }
-        if (a->rt == 15 && !a->l) {
-            return false;
-        }
+    if (!dc_isar_feature(aa32_fpsp_v2, s)) {
+        return false;
     }
 
     switch (a->reg) {
-- 
2.20.1



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

* [PULL 19/36] target/arm: Move general-use constant expanders up in translate.c
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (17 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 18/36] target/arm: Refactor M-profile VMSR/VMRS handling Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 20/36] target/arm: Implement VLDR/VSTR system register Peter Maydell
                   ` (17 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

The constant-expander functions like negate, plus_2, etc, are
generally useful; move them up in translate.c so we can use them in
the VFP/Neon decoders as well as in the A32/T32/T16 decoders.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-9-peter.maydell@linaro.org
---
 target/arm/translate.c | 46 +++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 47a1a5739c8..f5acd32e76a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -109,6 +109,30 @@ static void arm_gen_condlabel(DisasContext *s)
     }
 }
 
+/*
+ * Constant expanders for the decoders.
+ */
+
+static int negate(DisasContext *s, int x)
+{
+    return -x;
+}
+
+static int plus_2(DisasContext *s, int x)
+{
+    return x + 2;
+}
+
+static int times_2(DisasContext *s, int x)
+{
+    return x * 2;
+}
+
+static int times_4(DisasContext *s, int x)
+{
+    return x * 4;
+}
+
 /* Flags for the disas_set_da_iss info argument:
  * lower bits hold the Rt register number, higher bits are flags.
  */
@@ -5177,29 +5201,9 @@ static void arm_skip_unless(DisasContext *s, uint32_t cond)
 
 
 /*
- * Constant expanders for the decoders.
+ * Constant expanders used by T16/T32 decode
  */
 
-static int negate(DisasContext *s, int x)
-{
-    return -x;
-}
-
-static int plus_2(DisasContext *s, int x)
-{
-    return x + 2;
-}
-
-static int times_2(DisasContext *s, int x)
-{
-    return x * 2;
-}
-
-static int times_4(DisasContext *s, int x)
-{
-    return x * 4;
-}
-
 /* Return only the rotation part of T32ExpandImm.  */
 static int t32_expandimm_rot(DisasContext *s, int x)
 {
-- 
2.20.1



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

* [PULL 20/36] target/arm: Implement VLDR/VSTR system register
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (18 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 19/36] target/arm: Move general-use constant expanders up in translate.c Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 21/36] target/arm: Implement M-profile FPSCR_nzcvqc Peter Maydell
                   ` (16 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

Implement the new-in-v8.1M VLDR/VSTR variants which directly
read or write FP system registers to memory.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-10-peter.maydell@linaro.org
---
 target/arm/vfp.decode          | 14 ++++++
 target/arm/translate-vfp.c.inc | 91 ++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
index 1300ba045dd..6f7f28f9a46 100644
--- a/target/arm/vfp.decode
+++ b/target/arm/vfp.decode
@@ -84,6 +84,20 @@ VLDR_VSTR_hp ---- 1101 u:1 .0 l:1 rn:4 .... 1001 imm:8      vd=%vd_sp
 VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8      vd=%vd_sp
 VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8      vd=%vd_dp
 
+# M-profile VLDR/VSTR to sysreg
+%vldr_sysreg 22:1 13:3
+%imm7_0x4 0:7 !function=times_4
+
+&vldr_sysreg rn reg imm a w p
+@vldr_sysreg .... ... . a:1 . . . rn:4 ... . ... .. ....... \
+             reg=%vldr_sysreg imm=%imm7_0x4 &vldr_sysreg
+
+# P=0 W=0 is SEE "Related encodings", so split into two patterns
+VLDR_sysreg  ---- 110 1 . . w:1 1 .... ... 0 111 11 ....... @vldr_sysreg p=1
+VLDR_sysreg  ---- 110 0 . . 1   1 .... ... 0 111 11 ....... @vldr_sysreg p=0 w=1
+VSTR_sysreg  ---- 110 1 . . w:1 0 .... ... 0 111 11 ....... @vldr_sysreg p=1
+VSTR_sysreg  ---- 110 0 . . 1   0 .... ... 0 111 11 ....... @vldr_sysreg p=0 w=1
+
 # We split the load/store multiple up into two patterns to avoid
 # overlap with other insns in the "Advanced SIMD load/store and 64-bit move"
 # grouping:
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 7a0cbca6640..f884d680a03 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -913,6 +913,97 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
     return true;
 }
 
+static void fp_sysreg_to_memory(DisasContext *s, void *opaque, TCGv_i32 value)
+{
+    arg_vldr_sysreg *a = opaque;
+    uint32_t offset = a->imm;
+    TCGv_i32 addr;
+
+    if (!a->a) {
+        offset = - offset;
+    }
+
+    addr = load_reg(s, a->rn);
+    if (a->p) {
+        tcg_gen_addi_i32(addr, addr, offset);
+    }
+
+    if (s->v8m_stackcheck && a->rn == 13 && a->w) {
+        gen_helper_v8m_stackcheck(cpu_env, addr);
+    }
+
+    gen_aa32_st_i32(s, value, addr, get_mem_index(s),
+                    MO_UL | MO_ALIGN | s->be_data);
+    tcg_temp_free_i32(value);
+
+    if (a->w) {
+        /* writeback */
+        if (!a->p) {
+            tcg_gen_addi_i32(addr, addr, offset);
+        }
+        store_reg(s, a->rn, addr);
+    } else {
+        tcg_temp_free_i32(addr);
+    }
+}
+
+static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, void *opaque)
+{
+    arg_vldr_sysreg *a = opaque;
+    uint32_t offset = a->imm;
+    TCGv_i32 addr;
+    TCGv_i32 value = tcg_temp_new_i32();
+
+    if (!a->a) {
+        offset = - offset;
+    }
+
+    addr = load_reg(s, a->rn);
+    if (a->p) {
+        tcg_gen_addi_i32(addr, addr, offset);
+    }
+
+    if (s->v8m_stackcheck && a->rn == 13 && a->w) {
+        gen_helper_v8m_stackcheck(cpu_env, addr);
+    }
+
+    gen_aa32_ld_i32(s, value, addr, get_mem_index(s),
+                    MO_UL | MO_ALIGN | s->be_data);
+
+    if (a->w) {
+        /* writeback */
+        if (!a->p) {
+            tcg_gen_addi_i32(addr, addr, offset);
+        }
+        store_reg(s, a->rn, addr);
+    } else {
+        tcg_temp_free_i32(addr);
+    }
+    return value;
+}
+
+static bool trans_VLDR_sysreg(DisasContext *s, arg_vldr_sysreg *a)
+{
+    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+        return false;
+    }
+    if (a->rn == 15) {
+        return false;
+    }
+    return gen_M_fp_sysreg_write(s, a->reg, memory_to_fp_sysreg, a);
+}
+
+static bool trans_VSTR_sysreg(DisasContext *s, arg_vldr_sysreg *a)
+{
+    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+        return false;
+    }
+    if (a->rn == 15) {
+        return false;
+    }
+    return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_memory, a);
+}
+
 static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
 {
     TCGv_i32 tmp;
-- 
2.20.1



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

* [PULL 21/36] target/arm: Implement M-profile FPSCR_nzcvqc
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (19 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 20/36] target/arm: Implement VLDR/VSTR system register Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 22/36] target/arm: Use new FPCR_NZCV_MASK constant Peter Maydell
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

v8.1M defines a new FP system register FPSCR_nzcvqc; this behaves
like the existing FPSCR, except that it reads and writes only bits
[31:27] of the FPSCR (the N, Z, C, V and QC flag bits).  (Unlike the
FPSCR, the special case for Rt=15 of writing the CPSR.NZCV is not
permitted.)

Implement the register.  Since we don't yet implement MVE, we handle
the QC bit as RES0, with todo comments for where we will need to add
support later.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-11-peter.maydell@linaro.org
---
 target/arm/cpu.h               | 13 +++++++++++++
 target/arm/translate-vfp.c.inc | 27 +++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ad8b80c667d..04f6220b2f7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1524,6 +1524,13 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
 #define FPCR_FZ     (1 << 24)   /* Flush-to-zero enable bit */
 #define FPCR_DN     (1 << 25)   /* Default NaN enable bit */
 #define FPCR_QC     (1 << 27)   /* Cumulative saturation bit */
+#define FPCR_V      (1 << 28)   /* FP overflow flag */
+#define FPCR_C      (1 << 29)   /* FP carry flag */
+#define FPCR_Z      (1 << 30)   /* FP zero flag */
+#define FPCR_N      (1 << 31)   /* FP negative flag */
+
+#define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
+#define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
 
 static inline uint32_t vfp_get_fpsr(CPUARMState *env)
 {
@@ -1568,6 +1575,12 @@ enum arm_cpu_mode {
 #define ARM_VFP_FPEXC   8
 #define ARM_VFP_FPINST  9
 #define ARM_VFP_FPINST2 10
+/* These ones are M-profile only */
+#define ARM_VFP_FPSCR_NZCVQC 2
+#define ARM_VFP_VPR 12
+#define ARM_VFP_P0 13
+#define ARM_VFP_FPCXT_NS 14
+#define ARM_VFP_FPCXT_S 15
 
 /* QEMU-internal value meaning "FPSCR, but we care only about NZCV" */
 #define QEMU_VFP_FPSCR_NZCV 0xffff
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index f884d680a03..d698f3e1cd1 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -648,6 +648,11 @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
     case ARM_VFP_FPSCR:
     case QEMU_VFP_FPSCR_NZCV:
         break;
+    case ARM_VFP_FPSCR_NZCVQC:
+        if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+            return false;
+        }
+        break;
     default:
         return FPSysRegCheckFailed;
     }
@@ -683,6 +688,22 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
         tcg_temp_free_i32(tmp);
         gen_lookup_tb(s);
         break;
+    case ARM_VFP_FPSCR_NZCVQC:
+    {
+        TCGv_i32 fpscr;
+        tmp = loadfn(s, opaque);
+        /*
+         * TODO: when we implement MVE, write the QC bit.
+         * For non-MVE, QC is RES0.
+         */
+        tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
+        fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_gen_andi_i32(fpscr, fpscr, ~FPCR_NZCV_MASK);
+        tcg_gen_or_i32(fpscr, fpscr, tmp);
+        store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_temp_free_i32(tmp);
+        break;
+    }
     default:
         g_assert_not_reached();
     }
@@ -711,6 +732,12 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
         gen_helper_vfp_get_fpscr(tmp, cpu_env);
         storefn(s, opaque, tmp);
         break;
+    case ARM_VFP_FPSCR_NZCVQC:
+        /*
+         * TODO: MVE has a QC bit, which we probably won't store
+         * in the xregs[] field. For non-MVE, where QC is RES0,
+         * we can just fall through to the FPSCR_NZCV case.
+         */
     case QEMU_VFP_FPSCR_NZCV:
         /*
          * Read just NZCV; this is a special case to avoid the
-- 
2.20.1



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

* [PULL 22/36] target/arm: Use new FPCR_NZCV_MASK constant
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (20 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 21/36] target/arm: Implement M-profile FPSCR_nzcvqc Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 23/36] target/arm: Factor out preserve-fp-state from full_vfp_access_check() Peter Maydell
                   ` (14 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

We defined a constant name for the mask of NZCV bits in the FPCR/FPSCR
in the previous commit; use it in a couple of places in existing code,
where we're masking out everything except NZCV for the "load to Rt=15
sets CPSR.NZCV" special case.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-12-peter.maydell@linaro.org
---
 target/arm/translate-vfp.c.inc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index d698f3e1cd1..cd8d5b4f28b 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -744,7 +744,7 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
          * helper call for the "VMRS to CPSR.NZCV" insn.
          */
         tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
-        tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
+        tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
         storefn(s, opaque, tmp);
         break;
     default:
@@ -885,7 +885,7 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
         case ARM_VFP_FPSCR:
             if (a->rt == 15) {
                 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
-                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
+                tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
             } else {
                 tmp = tcg_temp_new_i32();
                 gen_helper_vfp_get_fpscr(tmp, cpu_env);
-- 
2.20.1



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

* [PULL 23/36] target/arm: Factor out preserve-fp-state from full_vfp_access_check()
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (21 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 22/36] target/arm: Use new FPCR_NZCV_MASK constant Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 24/36] target/arm: Implement FPCXT_S fp system register Peter Maydell
                   ` (13 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

Factor out the code which handles M-profile lazy FP state preservation
from full_vfp_access_check(); accesses to the FPCXT_NS register are
a special case which need to do just this part (corresponding in the
pseudocode to the PreserveFPState() function), and not the full
set of actions matching the pseudocode ExecuteFPCheck() which
normal FP instructions need to do.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20201119215617.29887-13-peter.maydell@linaro.org
---
 target/arm/translate-vfp.c.inc | 45 ++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index cd8d5b4f28b..bb1c41413e7 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -83,6 +83,32 @@ static inline long vfp_f16_offset(unsigned reg, bool top)
     return offs;
 }
 
+/*
+ * Generate code for M-profile lazy FP state preservation if needed;
+ * this corresponds to the pseudocode PreserveFPState() function.
+ */
+static void gen_preserve_fp_state(DisasContext *s)
+{
+    if (s->v7m_lspact) {
+        /*
+         * Lazy state saving affects external memory and also the NVIC,
+         * so we must mark it as an IO operation for icount (and cause
+         * this to be the last insn in the TB).
+         */
+        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+            s->base.is_jmp = DISAS_UPDATE_EXIT;
+            gen_io_start();
+        }
+        gen_helper_v7m_preserve_fp_state(cpu_env);
+        /*
+         * If the preserve_fp_state helper doesn't throw an exception
+         * then it will clear LSPACT; we don't need to repeat this for
+         * any further FP insns in this TB.
+         */
+        s->v7m_lspact = false;
+    }
+}
+
 /*
  * Check that VFP access is enabled. If it is, do the necessary
  * M-profile lazy-FP handling and then return true.
@@ -113,24 +139,7 @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
         /* Handle M-profile lazy FP state mechanics */
 
         /* Trigger lazy-state preservation if necessary */
-        if (s->v7m_lspact) {
-            /*
-             * Lazy state saving affects external memory and also the NVIC,
-             * so we must mark it as an IO operation for icount (and cause
-             * this to be the last insn in the TB).
-             */
-            if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                s->base.is_jmp = DISAS_UPDATE_EXIT;
-                gen_io_start();
-            }
-            gen_helper_v7m_preserve_fp_state(cpu_env);
-            /*
-             * If the preserve_fp_state helper doesn't throw an exception
-             * then it will clear LSPACT; we don't need to repeat this for
-             * any further FP insns in this TB.
-             */
-            s->v7m_lspact = false;
-        }
+        gen_preserve_fp_state(s);
 
         /* Update ownership of FP context: set FPCCR.S to match current state */
         if (s->v8m_fpccr_s_wrong) {
-- 
2.20.1



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

* [PULL 24/36] target/arm: Implement FPCXT_S fp system register
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (22 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 23/36] target/arm: Factor out preserve-fp-state from full_vfp_access_check() Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 25/36] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M Peter Maydell
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

Implement the new-in-v8.1M FPCXT_S floating point system register.
This is for saving and restoring the secure floating point context,
and it reads and writes bits [27:0] from the FPSCR and the
CONTROL.SFPA bit in bit [31].

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-14-peter.maydell@linaro.org
---
 target/arm/translate-vfp.c.inc | 58 ++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index bb1c41413e7..808b4077054 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -662,6 +662,14 @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
             return false;
         }
         break;
+    case ARM_VFP_FPCXT_S:
+        if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+            return false;
+        }
+        if (!s->v8m_secure) {
+            return false;
+        }
+        break;
     default:
         return FPSysRegCheckFailed;
     }
@@ -713,6 +721,26 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
         tcg_temp_free_i32(tmp);
         break;
     }
+    case ARM_VFP_FPCXT_S:
+    {
+        TCGv_i32 sfpa, control, fpscr;
+        /* Set FPSCR[27:0] and CONTROL.SFPA from value */
+        tmp = loadfn(s, opaque);
+        sfpa = tcg_temp_new_i32();
+        tcg_gen_shri_i32(sfpa, tmp, 31);
+        control = load_cpu_field(v7m.control[M_REG_S]);
+        tcg_gen_deposit_i32(control, control, sfpa,
+                            R_V7M_CONTROL_SFPA_SHIFT, 1);
+        store_cpu_field(control, v7m.control[M_REG_S]);
+        fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_gen_andi_i32(fpscr, fpscr, FPCR_NZCV_MASK);
+        tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
+        tcg_gen_or_i32(fpscr, fpscr, tmp);
+        store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
+        tcg_temp_free_i32(tmp);
+        tcg_temp_free_i32(sfpa);
+        break;
+    }
     default:
         g_assert_not_reached();
     }
@@ -756,6 +784,36 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
         tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
         storefn(s, opaque, tmp);
         break;
+    case ARM_VFP_FPCXT_S:
+    {
+        TCGv_i32 control, sfpa, fpscr;
+        /* Bits [27:0] from FPSCR, bit [31] from CONTROL.SFPA */
+        tmp = tcg_temp_new_i32();
+        sfpa = tcg_temp_new_i32();
+        gen_helper_vfp_get_fpscr(tmp, cpu_env);
+        tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
+        control = load_cpu_field(v7m.control[M_REG_S]);
+        tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
+        tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
+        tcg_gen_or_i32(tmp, tmp, sfpa);
+        tcg_temp_free_i32(sfpa);
+        /*
+         * Store result before updating FPSCR etc, in case
+         * it is a memory write which causes an exception.
+         */
+        storefn(s, opaque, tmp);
+        /*
+         * Now we must reset FPSCR from FPDSCR_NS, and clear
+         * CONTROL.SFPA; so we'll end the TB here.
+         */
+        tcg_gen_andi_i32(control, control, ~R_V7M_CONTROL_SFPA_MASK);
+        store_cpu_field(control, v7m.control[M_REG_S]);
+        fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
+        gen_helper_vfp_set_fpscr(cpu_env, fpscr);
+        tcg_temp_free_i32(fpscr);
+        gen_lookup_tb(s);
+        break;
+    }
     default:
         g_assert_not_reached();
     }
-- 
2.20.1



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

* [PULL 25/36] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (23 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 24/36] target/arm: Implement FPCXT_S fp system register Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 26/36] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry Peter Maydell
                   ` (11 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

The FPDSCR register has a similar layout to the FPSCR.  In v8.1M it
gains new fields FZ16 (if half-precision floating point is supported)
and LTPSIZE (always reads as 4).  Update the reset value and the code
that handles writes to this register accordingly.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-16-peter.maydell@linaro.org
---
 target/arm/cpu.h      | 5 +++++
 hw/intc/armv7m_nvic.c | 9 ++++++++-
 target/arm/cpu.c      | 3 +++
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 04f6220b2f7..47cb5032ce9 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1521,14 +1521,19 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
 #define FPCR_IXE    (1 << 12)   /* Inexact exception trap enable */
 #define FPCR_IDE    (1 << 15)   /* Input Denormal exception trap enable */
 #define FPCR_FZ16   (1 << 19)   /* ARMv8.2+, FP16 flush-to-zero */
+#define FPCR_RMODE_MASK (3 << 22) /* Rounding mode */
 #define FPCR_FZ     (1 << 24)   /* Flush-to-zero enable bit */
 #define FPCR_DN     (1 << 25)   /* Default NaN enable bit */
+#define FPCR_AHP    (1 << 26)   /* Alternative half-precision */
 #define FPCR_QC     (1 << 27)   /* Cumulative saturation bit */
 #define FPCR_V      (1 << 28)   /* FP overflow flag */
 #define FPCR_C      (1 << 29)   /* FP carry flag */
 #define FPCR_Z      (1 << 30)   /* FP zero flag */
 #define FPCR_N      (1 << 31)   /* FP negative flag */
 
+#define FPCR_LTPSIZE_SHIFT 16   /* LTPSIZE, M-profile only */
+#define FPCR_LTPSIZE_MASK (7 << FPCR_LTPSIZE_SHIFT)
+
 #define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
 #define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
 
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 9628ce876e0..be3bc1f1f45 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2068,7 +2068,14 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         break;
     case 0xf3c: /* FPDSCR */
         if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
-            value &= 0x07c00000;
+            uint32_t mask = FPCR_AHP | FPCR_DN | FPCR_FZ | FPCR_RMODE_MASK;
+            if (cpu_isar_feature(any_fp16, cpu)) {
+                mask |= FPCR_FZ16;
+            }
+            value &= mask;
+            if (cpu_isar_feature(aa32_lob, cpu)) {
+                value |= 4 << FPCR_LTPSIZE_SHIFT;
+            }
             cpu->env.v7m.fpdscr[attrs.secure] = value;
         }
         break;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 40f3f798b2b..d6188f6566a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -262,6 +262,9 @@ static void arm_cpu_reset(DeviceState *dev)
              * always reset to 4.
              */
             env->v7m.ltpsize = 4;
+            /* The LTPSIZE field in FPDSCR is constant and reads as 4. */
+            env->v7m.fpdscr[M_REG_NS] = 4 << FPCR_LTPSIZE_SHIFT;
+            env->v7m.fpdscr[M_REG_S] = 4 << FPCR_LTPSIZE_SHIFT;
         }
 
         if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
-- 
2.20.1



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

* [PULL 26/36] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (24 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 25/36] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 27/36] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures Peter Maydell
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

In v8.0M, on exception entry the registers R0-R3, R12, APSR and EPSR
are zeroed for an exception taken to Non-secure state; for an
exception taken to Secure state they become UNKNOWN, and we chose to
leave them at their previous values.

In v8.1M the behaviour is specified more tightly and these registers
are always zeroed regardless of the security state that the exception
targets (see rule R_KPZV).  Implement this.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-17-peter.maydell@linaro.org
---
 target/arm/m_helper.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index aad01ea0127..721b4b4896e 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -897,10 +897,12 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
          * Clear registers if necessary to prevent non-secure exception
          * code being able to see register values from secure code.
          * Where register values become architecturally UNKNOWN we leave
-         * them with their previous values.
+         * them with their previous values. v8.1M is tighter than v8.0M
+         * here and always zeroes the caller-saved registers regardless
+         * of the security state the exception is targeting.
          */
         if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
-            if (!targets_secure) {
+            if (!targets_secure || arm_feature(env, ARM_FEATURE_V8_1M)) {
                 /*
                  * Always clear the caller-saved registers (they have been
                  * pushed to the stack earlier in v7m_push_stack()).
@@ -909,10 +911,16 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
                  * v7m_push_callee_stack()).
                  */
                 int i;
+                /*
+                 * r4..r11 are callee-saves, zero only if background
+                 * state was Secure (EXCRET.S == 1) and exception
+                 * targets Non-secure state
+                 */
+                bool zero_callee_saves = !targets_secure &&
+                    (lr & R_V7M_EXCRET_S_MASK);
 
                 for (i = 0; i < 13; i++) {
-                    /* r4..r11 are callee-saves, zero only if EXCRET.S == 1 */
-                    if (i < 4 || i > 11 || (lr & R_V7M_EXCRET_S_MASK)) {
+                    if (i < 4 || i > 11 || zero_callee_saves) {
                         env->regs[i] = 0;
                     }
                 }
-- 
2.20.1



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

* [PULL 27/36] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (25 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 26/36] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 28/36] target/arm: Implement v8.1M REVIDR register Peter Maydell
                   ` (9 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

In v8.1M, vector table fetch failures don't set HFSR.FORCED (see rule
R_LLRP).  (In previous versions of the architecture this was either
required or IMPDEF.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-18-peter.maydell@linaro.org
---
 target/arm/m_helper.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 721b4b4896e..9cdc8a64c29 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -722,11 +722,15 @@ load_fail:
      * The HardFault is Secure if BFHFNMINS is 0 (meaning that all HFs are
      * secure); otherwise it targets the same security state as the
      * underlying exception.
+     * In v8.1M HardFaults from vector table fetch fails don't set FORCED.
      */
     if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
         exc_secure = true;
     }
-    env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK | R_V7M_HFSR_FORCED_MASK;
+    env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK;
+    if (!arm_feature(env, ARM_FEATURE_V8_1M)) {
+        env->v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
+    }
     armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
     return false;
 }
-- 
2.20.1



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

* [PULL 28/36] target/arm: Implement v8.1M REVIDR register
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (26 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 27/36] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 29/36] target/arm: Implement new v8.1M NOCP check for exception return Peter Maydell
                   ` (8 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

In v8.1M a REVIDR register is defined, which is at address 0xe00ecfc
and is a read-only IMPDEF register providing implementation specific
minor revision information, like the v8A REVIDR_EL1. Implement this.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-19-peter.maydell@linaro.org
---
 hw/intc/armv7m_nvic.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index be3bc1f1f45..effc4a784ca 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1025,6 +1025,11 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         }
         return val;
     }
+    case 0xcfc:
+        if (!arm_feature(&cpu->env, ARM_FEATURE_V8_1M)) {
+            goto bad_offset;
+        }
+        return cpu->revidr;
     case 0xd00: /* CPUID Base.  */
         return cpu->midr;
     case 0xd04: /* Interrupt Control State (ICSR) */
-- 
2.20.1



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

* [PULL 29/36] target/arm: Implement new v8.1M NOCP check for exception return
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (27 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 28/36] target/arm: Implement v8.1M REVIDR register Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 30/36] target/arm: Implement new v8.1M VLLDM and VLSTM encodings Peter Maydell
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

In v8.1M a new exception return check is added which may cause a NOCP
UsageFault (see rule R_XLTP): before we clear s0..s15 and the FPSCR
we must check whether access to CP10 from the Security state of the
returning exception is disabled; if it is then we must take a fault.

(Note that for our implementation CPPWR is always RAZ/WI and so can
never cause CP10 accesses to fail.)

The other v8.1M change to this register-clearing code is that if MVE
is implemented VPR must also be cleared, so add a TODO comment to
that effect.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-20-peter.maydell@linaro.org
---
 target/arm/m_helper.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 9cdc8a64c29..0bdd3cc10e9 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -1515,7 +1515,27 @@ static void do_v7m_exception_exit(ARMCPU *cpu)
             v7m_exception_taken(cpu, excret, true, false);
             return;
         } else {
-            /* Clear s0..s15 and FPSCR */
+            if (arm_feature(env, ARM_FEATURE_V8_1M)) {
+                /* v8.1M adds this NOCP check */
+                bool nsacr_pass = exc_secure ||
+                    extract32(env->v7m.nsacr, 10, 1);
+                bool cpacr_pass = v7m_cpacr_pass(env, exc_secure, true);
+                if (!nsacr_pass) {
+                    armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
+                    env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
+                    qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
+                        "stackframe: NSACR prevents clearing FPU registers\n");
+                    v7m_exception_taken(cpu, excret, true, false);
+                } else if (!cpacr_pass) {
+                    armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
+                                            exc_secure);
+                    env->v7m.cfsr[exc_secure] |= R_V7M_CFSR_NOCP_MASK;
+                    qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
+                        "stackframe: CPACR prevents clearing FPU registers\n");
+                    v7m_exception_taken(cpu, excret, true, false);
+                }
+            }
+            /* Clear s0..s15 and FPSCR; TODO also VPR when MVE is implemented */
             int i;
 
             for (i = 0; i < 16; i += 2) {
-- 
2.20.1



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

* [PULL 30/36] target/arm: Implement new v8.1M VLLDM and VLSTM encodings
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (28 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 29/36] target/arm: Implement new v8.1M NOCP check for exception return Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 31/36] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit Peter Maydell
                   ` (6 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

v8.1M adds new encodings of VLLDM and VLSTM (where bit 7 is set).
The only difference is that:
 * the old T1 encodings UNDEF if the implementation implements 32
   Dregs (this is currently architecturally impossible for M-profile)
 * the new T2 encodings have the implementation-defined option to
   read from memory (discarding the data) or write UNKNOWN values to
   memory for the stack slots that would be D16-D31

We choose not to make those accesses, so for us the two
instructions behave identically assuming they don't UNDEF.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-21-peter.maydell@linaro.org
---
 target/arm/m-nocp.decode       |  2 +-
 target/arm/translate-vfp.c.inc | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode
index ccd62e8739a..6699626d7cb 100644
--- a/target/arm/m-nocp.decode
+++ b/target/arm/m-nocp.decode
@@ -36,7 +36,7 @@
 
 {
   # Special cases which do not take an early NOCP: VLLDM and VLSTM
-  VLLDM_VLSTM  1110 1100 001 l:1 rn:4 0000 1010 0000 0000
+  VLLDM_VLSTM  1110 1100 001 l:1 rn:4 0000 1010 op:1 000 0000
   # VSCCLRM (new in v8.1M) is similar:
   VSCCLRM      1110 1100 1.01 1111 .... 1011 imm:7 0   vd=%vd_dp size=3
   VSCCLRM      1110 1100 1.01 1111 .... 1010 imm:8     vd=%vd_sp size=2
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 808b4077054..0db936084bd 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -3721,6 +3721,31 @@ static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
         !arm_dc_feature(s, ARM_FEATURE_V8)) {
         return false;
     }
+
+    if (a->op) {
+        /*
+         * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
+         * to take the IMPDEF option to make memory accesses to the stack
+         * slots that correspond to the D16-D31 registers (discarding
+         * read data and writing UNKNOWN values), so for us the T2
+         * encoding behaves identically to the T1 encoding.
+         */
+        if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+            return false;
+        }
+    } else {
+        /*
+         * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
+         * This is currently architecturally impossible, but we add the
+         * check to stay in line with the pseudocode. Note that we must
+         * emit code for the UNDEF so it takes precedence over the NOCP.
+         */
+        if (dc_isar_feature(aa32_simd_r32, s)) {
+            unallocated_encoding(s);
+            return true;
+        }
+    }
+
     /*
      * If not secure, UNDEF. We must emit code for this
      * rather than returning false so that this takes
-- 
2.20.1



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

* [PULL 31/36] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (29 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 30/36] target/arm: Implement new v8.1M VLLDM and VLSTM encodings Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 32/36] target/arm: Implement CCR_S.TRD behaviour for SG insns Peter Maydell
                   ` (5 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

v8.1M introduces a new TRD flag in the CCR register, which enables
checking for stack frame integrity signatures on SG instructions.
This bit is not banked, and is always RAZ/WI to Non-secure code.
Adjust the code for handling CCR reads and writes to handle this.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-23-peter.maydell@linaro.org
---
 target/arm/cpu.h      |  2 ++
 hw/intc/armv7m_nvic.c | 26 ++++++++++++++++++--------
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 47cb5032ce9..22c55c81933 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1611,6 +1611,8 @@ FIELD(V7M_CCR, STKOFHFNMIGN, 10, 1)
 FIELD(V7M_CCR, DC, 16, 1)
 FIELD(V7M_CCR, IC, 17, 1)
 FIELD(V7M_CCR, BP, 18, 1)
+FIELD(V7M_CCR, LOB, 19, 1)
+FIELD(V7M_CCR, TRD, 20, 1)
 
 /* V7M SCR bits */
 FIELD(V7M_SCR, SLEEPONEXIT, 1, 1)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index effc4a784ca..6f94f88a795 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1095,8 +1095,9 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
         }
         return cpu->env.v7m.scr[attrs.secure];
     case 0xd14: /* Configuration Control.  */
-        /* The BFHFNMIGN bit is the only non-banked bit; we
-         * keep it in the non-secure copy of the register.
+        /*
+         * Non-banked bits: BFHFNMIGN (stored in the NS copy of the register)
+         * and TRD (stored in the S copy of the register)
          */
         val = cpu->env.v7m.ccr[attrs.secure];
         val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
@@ -1639,17 +1640,25 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         cpu->env.v7m.scr[attrs.secure] = value;
         break;
     case 0xd14: /* Configuration Control.  */
+    {
+        uint32_t mask;
+
         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
             goto bad_offset;
         }
 
         /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
-        value &= (R_V7M_CCR_STKALIGN_MASK |
-                  R_V7M_CCR_BFHFNMIGN_MASK |
-                  R_V7M_CCR_DIV_0_TRP_MASK |
-                  R_V7M_CCR_UNALIGN_TRP_MASK |
-                  R_V7M_CCR_USERSETMPEND_MASK |
-                  R_V7M_CCR_NONBASETHRDENA_MASK);
+        mask = R_V7M_CCR_STKALIGN_MASK |
+            R_V7M_CCR_BFHFNMIGN_MASK |
+            R_V7M_CCR_DIV_0_TRP_MASK |
+            R_V7M_CCR_UNALIGN_TRP_MASK |
+            R_V7M_CCR_USERSETMPEND_MASK |
+            R_V7M_CCR_NONBASETHRDENA_MASK;
+        if (arm_feature(&cpu->env, ARM_FEATURE_V8_1M) && attrs.secure) {
+            /* TRD is always RAZ/WI from NS */
+            mask |= R_V7M_CCR_TRD_MASK;
+        }
+        value &= mask;
 
         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
             /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
@@ -1666,6 +1675,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
 
         cpu->env.v7m.ccr[attrs.secure] = value;
         break;
+    }
     case 0xd24: /* System Handler Control and State (SHCSR) */
         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
             goto bad_offset;
-- 
2.20.1



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

* [PULL 32/36] target/arm: Implement CCR_S.TRD behaviour for SG insns
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (30 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 31/36] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 33/36] hw/intc/armv7m_nvic: Fix "return from inactive handler" check Peter Maydell
                   ` (4 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

v8.1M introduces a new TRD flag in the CCR register, which enables
checking for stack frame integrity signatures on SG instructions.
Add the code in the SG insn implementation for the new behaviour.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-24-peter.maydell@linaro.org
---
 target/arm/m_helper.c | 86 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 0bdd3cc10e9..643dcafb83d 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -1999,6 +1999,64 @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
     return true;
 }
 
+static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
+                                   uint32_t addr, uint32_t *spdata)
+{
+    /*
+     * Read a word of data from the stack for the SG instruction,
+     * writing the value into *spdata. If the load succeeds, return
+     * true; otherwise pend an appropriate exception and return false.
+     * (We can't use data load helpers here that throw an exception
+     * because of the context we're called in, which is halfway through
+     * arm_v7m_cpu_do_interrupt().)
+     */
+    CPUState *cs = CPU(cpu);
+    CPUARMState *env = &cpu->env;
+    MemTxAttrs attrs = {};
+    MemTxResult txres;
+    target_ulong page_size;
+    hwaddr physaddr;
+    int prot;
+    ARMMMUFaultInfo fi = {};
+    ARMCacheAttrs cacheattrs = {};
+    uint32_t value;
+
+    if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &physaddr,
+                      &attrs, &prot, &page_size, &fi, &cacheattrs)) {
+        /* MPU/SAU lookup failed */
+        if (fi.type == ARMFault_QEMU_SFault) {
+            qemu_log_mask(CPU_LOG_INT,
+                          "...SecureFault during stack word read\n");
+            env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
+            env->v7m.sfar = addr;
+            armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
+        } else {
+            qemu_log_mask(CPU_LOG_INT,
+                          "...MemManageFault during stack word read\n");
+            env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_DACCVIOL_MASK |
+                R_V7M_CFSR_MMARVALID_MASK;
+            env->v7m.mmfar[M_REG_S] = addr;
+            armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, false);
+        }
+        return false;
+    }
+    value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
+                              attrs, &txres);
+    if (txres != MEMTX_OK) {
+        /* BusFault trying to read the data */
+        qemu_log_mask(CPU_LOG_INT,
+                      "...BusFault during stack word read\n");
+        env->v7m.cfsr[M_REG_NS] |=
+            (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
+        env->v7m.bfar = addr;
+        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
+        return false;
+    }
+
+    *spdata = value;
+    return true;
+}
+
 static bool v7m_handle_execute_nsc(ARMCPU *cpu)
 {
     /*
@@ -2055,6 +2113,34 @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
      */
     qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
                   ", executing it\n", env->regs[15]);
+
+    if (cpu_isar_feature(aa32_m_sec_state, cpu) &&
+        !arm_v7m_is_handler_mode(env)) {
+        /*
+         * v8.1M exception stack frame integrity check. Note that we
+         * must perform the memory access even if CCR_S.TRD is zero
+         * and we aren't going to check what the data loaded is.
+         */
+        uint32_t spdata, sp;
+
+        /*
+         * We know we are currently NS, so the S stack pointers must be
+         * in other_ss_{psp,msp}, not in regs[13]/other_sp.
+         */
+        sp = v7m_using_psp(env) ? env->v7m.other_ss_psp : env->v7m.other_ss_msp;
+        if (!v7m_read_sg_stack_word(cpu, mmu_idx, sp, &spdata)) {
+            /* Stack access failed and an exception has been pended */
+            return false;
+        }
+
+        if (env->v7m.ccr[M_REG_S] & R_V7M_CCR_TRD_MASK) {
+            if (((spdata & ~1) == 0xfefa125a) ||
+                !(env->v7m.control[M_REG_S] & 1)) {
+                goto gen_invep;
+            }
+        }
+    }
+
     env->regs[14] &= ~1;
     env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
     switch_v7m_security_state(env, true);
-- 
2.20.1



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

* [PULL 33/36] hw/intc/armv7m_nvic: Fix "return from inactive handler" check
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (31 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 32/36] target/arm: Implement CCR_S.TRD behaviour for SG insns Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 34/36] target/arm: Implement M-profile "minimal RAS implementation" Peter Maydell
                   ` (3 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

In commit 077d7449100d824a4 we added code to handle the v8M
requirement that returns from NMI or HardFault forcibly deactivate
those exceptions regardless of what interrupt the guest is trying to
deactivate.  Unfortunately this broke the handling of the "illegal
exception return because the returning exception number is not
active" check for those cases.  In the pseudocode this test is done
on the exception the guest asks to return from, but because our
implementation was doing this in armv7m_nvic_complete_irq() after the
new "deactivate NMI/HardFault regardless" code we ended up doing the
test on the VecInfo for that exception instead, which usually meant
failing to raise the illegal exception return fault.

In the case for "configurable exception targeting the opposite
security state" we detected the illegal-return case but went ahead
and deactivated the VecInfo anyway, which is wrong because that is
the VecInfo for the other security state.

Rearrange the code so that we first identify the illegal return
cases, then see if we really need to deactivate NMI or HardFault
instead, and finally do the deactivation.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-25-peter.maydell@linaro.org
---
 hw/intc/armv7m_nvic.c | 59 +++++++++++++++++++++++--------------------
 1 file changed, 32 insertions(+), 27 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 6f94f88a795..cf233c05616 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -832,10 +832,40 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
 {
     NVICState *s = (NVICState *)opaque;
     VecInfo *vec = NULL;
-    int ret;
+    int ret = 0;
 
     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
 
+    trace_nvic_complete_irq(irq, secure);
+
+    if (secure && exc_is_banked(irq)) {
+        vec = &s->sec_vectors[irq];
+    } else {
+        vec = &s->vectors[irq];
+    }
+
+    /*
+     * Identify illegal exception return cases. We can't immediately
+     * return at this point because we still need to deactivate
+     * (either this exception or NMI/HardFault) first.
+     */
+    if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
+        /*
+         * Return from a configurable exception targeting the opposite
+         * security state from the one we're trying to complete it for.
+         * Clear vec because it's not really the VecInfo for this
+         * (irq, secstate) so we mustn't deactivate it.
+         */
+        ret = -1;
+        vec = NULL;
+    } else if (!vec->active) {
+        /* Return from an inactive interrupt */
+        ret = -1;
+    } else {
+        /* Legal return, we will return the RETTOBASE bit value to the caller */
+        ret = nvic_rettobase(s);
+    }
+
     /*
      * For negative priorities, v8M will forcibly deactivate the appropriate
      * NMI or HardFault regardless of what interrupt we're being asked to
@@ -865,32 +895,7 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
     }
 
     if (!vec) {
-        if (secure && exc_is_banked(irq)) {
-            vec = &s->sec_vectors[irq];
-        } else {
-            vec = &s->vectors[irq];
-        }
-    }
-
-    trace_nvic_complete_irq(irq, secure);
-
-    if (!vec->active) {
-        /* Tell the caller this was an illegal exception return */
-        return -1;
-    }
-
-    /*
-     * If this is a configurable exception and it is currently
-     * targeting the opposite security state from the one we're trying
-     * to complete it for, this counts as an illegal exception return.
-     * We still need to deactivate whatever vector the logic above has
-     * selected, though, as it might not be the same as the one for the
-     * requested exception number.
-     */
-    if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
-        ret = -1;
-    } else {
-        ret = nvic_rettobase(s);
+        return ret;
     }
 
     vec->active = 0;
-- 
2.20.1



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

* [PULL 34/36] target/arm: Implement M-profile "minimal RAS implementation"
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (32 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 33/36] hw/intc/armv7m_nvic: Fix "return from inactive handler" check Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 35/36] hw/intc/armv7m_nvic: Implement read/write for RAS register block Peter Maydell
                   ` (2 subsequent siblings)
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

For v8.1M the architecture mandates that CPUs must provide at
least the "minimal RAS implementation" from the Reliability,
Availability and Serviceability extension. This consists of:
 * an ESB instruction which is a NOP
   -- since it is in the HINT space we need only add a comment
 * an RFSR register which will RAZ/WI
 * a RAZ/WI AIRCR.IESB bit
   -- the code which handles writes to AIRCR does not allow setting
      of RES0 bits, so we already treat this as RAZ/WI; add a comment
      noting that this is deliberate
 * minimal implementation of the RAS register block at 0xe0005000
   -- this will be in a subsequent commit
 * setting the ID_PFR0.RAS field to 0b0010
   -- we will do this when we add the Cortex-M55 CPU model

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-26-peter.maydell@linaro.org
---
 target/arm/cpu.h      | 14 ++++++++++++++
 target/arm/t32.decode |  4 ++++
 hw/intc/armv7m_nvic.c | 13 +++++++++++++
 3 files changed, 31 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 22c55c81933..7e6c881a7e2 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1827,6 +1827,15 @@ FIELD(ID_MMFR4, LSM, 20, 4)
 FIELD(ID_MMFR4, CCIDX, 24, 4)
 FIELD(ID_MMFR4, EVT, 28, 4)
 
+FIELD(ID_PFR0, STATE0, 0, 4)
+FIELD(ID_PFR0, STATE1, 4, 4)
+FIELD(ID_PFR0, STATE2, 8, 4)
+FIELD(ID_PFR0, STATE3, 12, 4)
+FIELD(ID_PFR0, CSV2, 16, 4)
+FIELD(ID_PFR0, AMU, 20, 4)
+FIELD(ID_PFR0, DIT, 24, 4)
+FIELD(ID_PFR0, RAS, 28, 4)
+
 FIELD(ID_PFR1, PROGMOD, 0, 4)
 FIELD(ID_PFR1, SECURITY, 4, 4)
 FIELD(ID_PFR1, MPROGMOD, 8, 4)
@@ -3573,6 +3582,11 @@ static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
     return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
 }
 
+static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
+{
+    return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0;
+}
+
 static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
 {
     return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
index f045eb62c84..8b2c487fa7a 100644
--- a/target/arm/t32.decode
+++ b/target/arm/t32.decode
@@ -307,6 +307,10 @@ CLZ              1111 1010 1011 ---- 1111 .... 1000 ....      @rdm
       # SEV      1111 0011 1010 1111 1000 0000 0000 0100
       # SEVL     1111 0011 1010 1111 1000 0000 0000 0101
 
+      # For M-profile minimal-RAS ESB can be a NOP, which is the
+      # default behaviour since it is in the hint space.
+      # ESB      1111 0011 1010 1111 1000 0000 0001 0000
+
       # The canonical nop ends in 0000 0000, but the whole rest
       # of the space is "reserved hint, behaves as nop".
       NOP        1111 0011 1010 1111 1000 0000 ---- ----
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index cf233c05616..01e331ab1e4 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1483,6 +1483,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
             return 0;
         }
         return cpu->env.v7m.sfar;
+    case 0xf04: /* RFSR */
+        if (!cpu_isar_feature(aa32_ras, cpu)) {
+            goto bad_offset;
+        }
+        /* We provide minimal-RAS only: RFSR is RAZ/WI */
+        return 0;
     case 0xf34: /* FPCCR */
         if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
             return 0;
@@ -1611,6 +1617,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
                               R_V7M_AIRCR_PRIGROUP_SHIFT,
                               R_V7M_AIRCR_PRIGROUP_LENGTH);
             }
+            /* AIRCR.IESB is RAZ/WI because we implement only minimal RAS */
             if (attrs.secure) {
                 /* These bits are only writable by secure */
                 cpu->env.v7m.aircr = value &
@@ -2026,6 +2033,12 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
         }
         break;
     }
+    case 0xf04: /* RFSR */
+        if (!cpu_isar_feature(aa32_ras, cpu)) {
+            goto bad_offset;
+        }
+        /* We provide minimal-RAS only: RFSR is RAZ/WI */
+        break;
     case 0xf34: /* FPCCR */
         if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
             /* Not all bits here are banked. */
-- 
2.20.1



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

* [PULL 35/36] hw/intc/armv7m_nvic: Implement read/write for RAS register block
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (33 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 34/36] target/arm: Implement M-profile "minimal RAS implementation" Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 11:47 ` [PULL 36/36] hw/arm/armv7m: Correct typo in QOM object name Peter Maydell
  2020-12-10 12:51 ` [PULL 00/36] target-arm queue Peter Maydell
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

The RAS feature has a block of memory-mapped registers at offset
0x5000 within the PPB.  For a "minimal RAS" implementation we provide
no error records and so the only registers that exist in the block
are ERRIIDR and ERRDEVID.

The "RAZ/WI for privileged, BusFault for nonprivileged" behaviour
of the "nvic-default" region is actually valid for minimal-RAS,
so the main benefit of providing an explicit implementation of
the register block is more accurate LOG_UNIMP messages, and a
framework for where we could add a real RAS implementation later
if necessary.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-27-peter.maydell@linaro.org
---
 include/hw/intc/armv7m_nvic.h |  1 +
 hw/intc/armv7m_nvic.c         | 56 +++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index 33b6d8810c7..39c71e15936 100644
--- a/include/hw/intc/armv7m_nvic.h
+++ b/include/hw/intc/armv7m_nvic.h
@@ -83,6 +83,7 @@ struct NVICState {
     MemoryRegion sysreg_ns_mem;
     MemoryRegion systickmem;
     MemoryRegion systick_ns_mem;
+    MemoryRegion ras_mem;
     MemoryRegion container;
     MemoryRegion defaultmem;
 
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 01e331ab1e4..f63aa2d8713 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2519,6 +2519,56 @@ static const MemoryRegionOps nvic_systick_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+
+static MemTxResult ras_read(void *opaque, hwaddr addr,
+                            uint64_t *data, unsigned size,
+                            MemTxAttrs attrs)
+{
+    if (attrs.user) {
+        return MEMTX_ERROR;
+    }
+
+    switch (addr) {
+    case 0xe10: /* ERRIIDR */
+        /* architect field = Arm; product/variant/revision 0 */
+        *data = 0x43b;
+        break;
+    case 0xfc8: /* ERRDEVID */
+        /* Minimal RAS: we implement 0 error record indexes */
+        *data = 0;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "Read RAS register offset 0x%x\n",
+                      (uint32_t)addr);
+        *data = 0;
+        break;
+    }
+    return MEMTX_OK;
+}
+
+static MemTxResult ras_write(void *opaque, hwaddr addr,
+                             uint64_t value, unsigned size,
+                             MemTxAttrs attrs)
+{
+    if (attrs.user) {
+        return MEMTX_ERROR;
+    }
+
+    switch (addr) {
+    default:
+        qemu_log_mask(LOG_UNIMP, "Write to RAS register offset 0x%x\n",
+                      (uint32_t)addr);
+        break;
+    }
+    return MEMTX_OK;
+}
+
+static const MemoryRegionOps ras_ops = {
+    .read_with_attrs = ras_read,
+    .write_with_attrs = ras_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 /*
  * Unassigned portions of the PPB space are RAZ/WI for privileged
  * accesses, and fault for non-privileged accesses.
@@ -2866,6 +2916,12 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
                                             &s->systick_ns_mem, 1);
     }
 
+    if (cpu_isar_feature(aa32_ras, s->cpu)) {
+        memory_region_init_io(&s->ras_mem, OBJECT(s),
+                              &ras_ops, s, "nvic_ras", 0x1000);
+        memory_region_add_subregion(&s->container, 0x5000, &s->ras_mem);
+    }
+
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
 }
 
-- 
2.20.1



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

* [PULL 36/36] hw/arm/armv7m: Correct typo in QOM object name
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (34 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 35/36] hw/intc/armv7m_nvic: Implement read/write for RAS register block Peter Maydell
@ 2020-12-10 11:47 ` Peter Maydell
  2020-12-10 12:51 ` [PULL 00/36] target-arm queue Peter Maydell
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 11:47 UTC (permalink / raw)
  To: qemu-devel

Correct a typo in the name we give the NVIC object.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201119215617.29887-28-peter.maydell@linaro.org
---
 hw/arm/armv7m.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 944f261dd05..8224d4ade9f 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -136,7 +136,7 @@ static void armv7m_instance_init(Object *obj)
 
     memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
 
-    object_initialize_child(obj, "nvnic", &s->nvic, TYPE_NVIC);
+    object_initialize_child(obj, "nvic", &s->nvic, TYPE_NVIC);
     object_property_add_alias(obj, "num-irq",
                               OBJECT(&s->nvic), "num-irq");
 
-- 
2.20.1



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

* Re: [PULL 00/36] target-arm queue
  2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
                   ` (35 preceding siblings ...)
  2020-12-10 11:47 ` [PULL 36/36] hw/arm/armv7m: Correct typo in QOM object name Peter Maydell
@ 2020-12-10 12:51 ` Peter Maydell
  36 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2020-12-10 12:51 UTC (permalink / raw)
  To: QEMU Developers

On Thu, 10 Dec 2020 at 11:47, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> First pullreq for 6.0: mostly my v8.1M work, plus some other
> bits and pieces. (I still have a lot of stuff in my to-review
> folder, which I may or may not get to before the Christmas break...)
>
> thanks
> -- PMM
>
> The following changes since commit 5e7b204dbfae9a562fc73684986f936b97f63877:
>
>   Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2020-12-09 20:08:54 +0000)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201210
>
> for you to fetch changes up to 71f916be1c7e9ede0e37d9cabc781b5a9e8638ff:
>
>   hw/arm/armv7m: Correct typo in QOM object name (2020-12-10 11:44:56 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * hw/arm/smmuv3: Fix up L1STD_SPAN decoding
>  * xlnx-zynqmp: Support Xilinx ZynqMP CAN controllers
>  * sbsa-ref: allow to use Cortex-A53/57/72 cpus
>  * Various minor code cleanups
>  * hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault
>  * Implement more pieces of ARMv8.1M support


Applied, thanks.

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

-- PMM


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

* [PULL 00/36] target-arm queue
@ 2024-01-26 14:33 Peter Maydell
  2024-01-27 13:00 ` Peter Maydell
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2024-01-26 14:33 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit 5bab95dc74d43bbb28c6a96d24c810a664432057:

  Merge tag 'pull-request-2024-01-24' of https://gitlab.com/thuth/qemu into staging (2024-01-25 12:33:42 +0000)

are available in the Git repository at:

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

for you to fetch changes up to 5e6be95ed1578c7cfac2082b39384d99fd912508:

  hw/arm: add PCIe to Freescale i.MX6 (2024-01-26 12:23:04 +0000)

----------------------------------------------------------------
target-arm queue:
 * Fix VNCR fault detection logic
 * Fix A64 scalar SQSHRN and SQRSHRN
 * Fix incorrect aa64_tidcp1 feature check
 * hw/arm/virt.c: Remove newline from error_report() string
 * hw/arm/musicpal: Convert to qemu_add_kbd_event_handler()
 * hw/arm/allwinner-a10: Unconditionally map the USB Host controllers
 * hw/arm/nseries: Unconditionally map the TUSB6010 USB Host controller
 * hw/arm: Add EHCI/OHCI controllers to Allwinner R40 and Bananapi board
 * hw/arm: Add AHCI/SATA controller to Allwinner R40 and Bananapi board
 * hw/arm: Add watchdog timer to Allwinner H40 and Bananapi board
 * arm: various include header cleanups
 * cleanups to allow some files to be built only once
 * fsl-imx6ul: Add various missing unimplemented devices
 * docs/system/arm/virt.rst: Add note on CPU features off by default
 * hw/char/imx_serial: Implement receive FIFO and ageing timer
 * target/xtensa: fix OOB TLB entry access
 * bswap.h: Fix const_le64() macro
 * hw/arm: add PCIe to Freescale i.MX6

----------------------------------------------------------------
Guenter Roeck (4):
      hw/arm: Add EHCI/OHCI controllers to Allwinner R40 and Bananapi board
      hw/arm: Add AHCI/SATA controller to Allwinner R40 and Bananapi board
      hw/arm: Add watchdog timer to Allwinner H40 and Bananapi board
      fsl-imx6ul: Add various missing unimplemented devices

Gustavo Romero (1):
      docs/system/arm/virt.rst: Add note on CPU features off by default

Max Filippov (1):
      target/xtensa: fix OOB TLB entry access

Nikita Ostrenkov (1):
      hw/arm: add PCIe to Freescale i.MX6

Peter Maydell (6):
      target/arm: Fix VNCR fault detection logic
      hw/arm/virt.c: Remove newline from error_report() string
      hw/arm/musicpal: Convert to qemu_add_kbd_event_handler()
      target/arm: Fix A64 scalar SQSHRN and SQRSHRN
      bswap.h: Fix const_le64() macro
      target/arm: Fix incorrect aa64_tidcp1 feature check

Philippe Mathieu-Daudé (20):
      hw/arm/allwinner-a10: Unconditionally map the USB Host controllers
      hw/arm/nseries: Unconditionally map the TUSB6010 USB Host controller
      hw/arm/exynos4210: Include missing 'exec/tswap.h' header
      hw/arm/xilinx_zynq: Include missing 'exec/tswap.h' header
      hw/arm/smmuv3: Include missing 'hw/registerfields.h' header
      hw/arm/xlnx-versal: Include missing 'cpu.h' header
      target/arm/cpu-features: Include missing 'hw/registerfields.h' header
      target/arm/cpregs: Include missing 'hw/registerfields.h' header
      target/arm/cpregs: Include missing 'kvm-consts.h' header
      target/arm: Expose arm_cpu_mp_affinity() in 'multiprocessing.h' header
      target/arm: Declare ARM_CPU_TYPE_NAME/SUFFIX in 'cpu-qom.h'
      hw/cpu/a9mpcore: Build it only once
      hw/misc/xlnx-versal-crl: Include generic 'cpu-qom.h' instead of 'cpu.h'
      hw/misc/xlnx-versal-crl: Build it only once
      target/arm: Expose M-profile register bank index definitions
      hw/arm/armv7m: Make 'hw/intc/armv7m_nvic.h' a target agnostic header
      target/arm: Move ARM_CPU_IRQ/FIQ definitions to 'cpu-qom.h' header
      target/arm: Move e2h_access() helper around
      target/arm: Move GTimer definitions to new 'gtimer.h' header
      hw/arm: Build various units only once

Rayhan Faizel (1):
      hw/char/imx_serial: Implement receive FIFO and ageing timer

Richard Henderson (2):
      target/arm: Rename arm_cpu_mp_affinity
      target/arm: Create arm_cpu_mp_affinity

 docs/system/arm/bananapi_m2u.rst  |   5 +-
 docs/system/arm/virt.rst          |  13 ++++
 hw/arm/smmuv3-internal.h          |   1 +
 include/hw/arm/allwinner-r40.h    |  15 +++++
 include/hw/arm/fsl-imx6.h         |  44 +++++++------
 include/hw/arm/fsl-imx6ul.h       |   2 +
 include/hw/arm/xlnx-versal.h      |   1 +
 include/hw/char/imx_serial.h      |  20 +++++-
 include/hw/intc/armv7m_nvic.h     |   2 +-
 include/hw/misc/xlnx-versal-crl.h |   2 +-
 include/qemu/bswap.h              |  16 ++---
 target/arm/cpregs.h               |   3 +
 target/arm/cpu-features.h         |   4 +-
 target/arm/cpu-qom.h              |  24 +++++++
 target/arm/cpu.h                  |  34 +---------
 target/arm/gtimer.h               |  21 ++++++
 target/arm/multiprocessing.h      |  16 +++++
 hw/arm/allwinner-a10.c            |  50 ++++++--------
 hw/arm/allwinner-h3.c             |   2 +
 hw/arm/allwinner-r40.c            |  69 +++++++++++++++++++-
 hw/arm/armv7m.c                   |   2 +
 hw/arm/aspeed_ast2400.c           |   1 +
 hw/arm/aspeed_ast2600.c           |   1 +
 hw/arm/bcm2836.c                  |   2 +
 hw/arm/collie.c                   |   1 -
 hw/arm/exynos4210.c               |   2 +
 hw/arm/fsl-imx25.c                |   1 +
 hw/arm/fsl-imx31.c                |   1 +
 hw/arm/fsl-imx6.c                 |  26 ++++++++
 hw/arm/fsl-imx6ul.c               |  31 +++++++++
 hw/arm/fsl-imx7.c                 |   1 +
 hw/arm/gumstix.c                  |   1 -
 hw/arm/highbank.c                 |   1 +
 hw/arm/integratorcp.c             |   2 +-
 hw/arm/mainstone.c                |   1 -
 hw/arm/musicpal.c                 | 133 ++++++++++++++++++--------------------
 hw/arm/npcm7xx.c                  |   3 +-
 hw/arm/nseries.c                  |   4 +-
 hw/arm/omap1.c                    |   1 +
 hw/arm/omap2.c                    |   2 +-
 hw/arm/omap_sx1.c                 |   1 -
 hw/arm/palm.c                     |   1 -
 hw/arm/realview.c                 |   1 +
 hw/arm/sbsa-ref.c                 |   4 +-
 hw/arm/spitz.c                    |   1 -
 hw/arm/strongarm.c                |   2 +-
 hw/arm/versatilepb.c              |   2 +-
 hw/arm/vexpress.c                 |   2 +-
 hw/arm/virt-acpi-build.c          |   4 +-
 hw/arm/virt.c                     |  15 +++--
 hw/arm/xilinx_zynq.c              |   3 +-
 hw/arm/xlnx-versal-virt.c         |   5 +-
 hw/arm/xlnx-versal.c              |   2 +
 hw/arm/xlnx-zynqmp.c              |   2 +
 hw/arm/z2.c                       |   1 -
 hw/char/imx_serial.c              | 102 +++++++++++++++++++++++++----
 hw/cpu/a15mpcore.c                |   1 +
 hw/cpu/a9mpcore.c                 |   2 +-
 hw/misc/xlnx-versal-crl.c         |   5 +-
 target/arm/arm-powerctl.c         |   3 +-
 target/arm/cpu.c                  |  13 +++-
 target/arm/helper.c               |  30 +++++----
 target/arm/hvf/hvf.c              |   6 +-
 target/arm/kvm.c                  |   1 +
 target/arm/machine.c              |   1 +
 target/arm/tcg/psci.c             |   3 +-
 target/arm/tcg/tlb_helper.c       |   2 +-
 target/arm/tcg/translate-a64.c    |   2 +-
 target/xtensa/mmu_helper.c        |  47 ++++++++++----
 hw/arm/Kconfig                    |   6 ++
 hw/arm/meson.build                |  23 +++----
 hw/cpu/meson.build                |   2 +-
 hw/misc/meson.build               |   2 +-
 73 files changed, 597 insertions(+), 261 deletions(-)
 create mode 100644 target/arm/gtimer.h
 create mode 100644 target/arm/multiprocessing.h


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

* Re: [PULL 00/36] target-arm queue
  2024-01-26 14:33 Peter Maydell
@ 2024-01-27 13:00 ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2024-01-27 13:00 UTC (permalink / raw)
  To: qemu-devel

On Fri, 26 Jan 2024 at 14:33, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> The following changes since commit 5bab95dc74d43bbb28c6a96d24c810a664432057:
>
>   Merge tag 'pull-request-2024-01-24' of https://gitlab.com/thuth/qemu into staging (2024-01-25 12:33:42 +0000)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240126
>
> for you to fetch changes up to 5e6be95ed1578c7cfac2082b39384d99fd912508:
>
>   hw/arm: add PCIe to Freescale i.MX6 (2024-01-26 12:23:04 +0000)
>
> ----------------------------------------------------------------
> target-arm queue:
>  * Fix VNCR fault detection logic
>  * Fix A64 scalar SQSHRN and SQRSHRN
>  * Fix incorrect aa64_tidcp1 feature check
>  * hw/arm/virt.c: Remove newline from error_report() string
>  * hw/arm/musicpal: Convert to qemu_add_kbd_event_handler()
>  * hw/arm/allwinner-a10: Unconditionally map the USB Host controllers
>  * hw/arm/nseries: Unconditionally map the TUSB6010 USB Host controller
>  * hw/arm: Add EHCI/OHCI controllers to Allwinner R40 and Bananapi board
>  * hw/arm: Add AHCI/SATA controller to Allwinner R40 and Bananapi board
>  * hw/arm: Add watchdog timer to Allwinner H40 and Bananapi board
>  * arm: various include header cleanups
>  * cleanups to allow some files to be built only once
>  * fsl-imx6ul: Add various missing unimplemented devices
>  * docs/system/arm/virt.rst: Add note on CPU features off by default
>  * hw/char/imx_serial: Implement receive FIFO and ageing timer
>  * target/xtensa: fix OOB TLB entry access
>  * bswap.h: Fix const_le64() macro
>  * hw/arm: add PCIe to Freescale i.MX6


Applied, thanks.

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

-- PMM


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

* [PULL 00/36] target-arm queue
@ 2024-02-02 15:36 Peter Maydell
  2024-02-03 13:27 ` Peter Maydell
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2024-02-02 15:36 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit c3709fde5955d13f6d4f86ab46ef3cc2288ca65e:

  Merge tag 'pull-aspeed-20240201' of https://github.com/legoater/qemu into staging (2024-02-01 14:42:11 +0000)

are available in the Git repository at:

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

for you to fetch changes up to f09c2b7ba9908714a3e2f1decd989462536cf731:

  hw/arm: Connect SPI Controller to BCM2835 (2024-02-02 13:51:59 +0000)

----------------------------------------------------------------
target/arm: fix exception syndrome for AArch32 bkpt insn
pci, vmbus, adb, s390x/css-bridge: Switch buses to 3-phase reset
system/vl.c: Fix handling of '-serial none -serial something'
target/arm: Add ID_AA64ZFR0_EL1.B16B16 to the exposed-to-userspace set
tests/qtest/xlnx-versal-trng-test.c: Drop use of variable length array
target/arm: Reinstate "vfp" property on AArch32 CPUs
doc/sphinx/hxtool.py: add optional label argument to SRST directive
hw/arm: Check for CPU types in machine_run_board_init() for various boards
pci-host: designware: Limit value range of iATU viewport register
hw/arm: Convert some DPRINTF macros to trace events and guest errors
hw/arm: NPCM7XX SoC: Add GMAC ethernet controller devices
hw/arm: Implement BCM2835 SPI Controller

----------------------------------------------------------------
David Woodhouse (1):
      doc/sphinx/hxtool.py: add optional label argument to SRST directive

Guenter Roeck (1):
      pci-host: designware: Limit value range of iATU viewport register

Hao Wu (2):
      hw/net: Add NPCMXXX GMAC device
      hw/arm: Add GMAC devices to NPCM7XX SoC

Jan Klötzke (1):
      target/arm: fix exception syndrome for AArch32 bkpt insn

Manos Pitsidianakis (6):
      hw/arm/strongarm.c: convert DPRINTF to trace events and guest errors
      hw/arm/z2: convert DPRINTF to trace events and guest errors
      hw/arm/xen_arm.c: convert DPRINTF to trace events and error/warn reports
      hw/xen/xen-mapcache.c: convert DPRINTF to tracepoints
      hw/xen/xen-hvm-common.c: convert DPRINTF to tracepoints
      hw/xen: convert stderr prints to error/warn reports

Nabih Estefan Diaz (4):
      tests/qtest: Creating qtest for GMAC Module
      hw/net: GMAC Rx Implementation
      hw/net: GMAC Tx Implementation
      tests/qtest: Adding PCS Module test to GMAC Qtest

Peter Maydell (10):
      pci: Switch bus reset to 3-phase-reset
      vmbus: Switch bus reset to 3-phase-reset
      adb: Switch bus reset to 3-phase-reset
      hw/s390x/css-bridge: switch virtual-css bus to 3-phase-reset
      hw/core: Remove transitional infrastructure from BusClass
      system/vl.c: Fix handling of '-serial none -serial something'
      qemu-options.hx: Improve -serial option documentation
      target/arm: Add ID_AA64ZFR0_EL1.B16B16 to the exposed-to-userspace set
      tests/qtest/xlnx-versal-trng-test.c: Drop use of variable length array
      target/arm: Reinstate "vfp" property on AArch32 CPUs

Philippe Mathieu-Daudé (9):
      hw/arm/exynos: Add missing QOM parent for CPU cores
      hw/arm/exynos: Check for CPU types in machine_run_board_init()
      hw/arm/highbank: Add missing QOM parent for CPU cores
      hw/arm/highbank: Check for CPU types in machine_run_board_init()
      hw/arm/msf2: Simplify setting MachineClass::valid_cpu_types[]
      hw/arm/musca: Simplify setting MachineClass::valid_cpu_types[]
      hw/arm/npcm7xx_boards: Simplify setting MachineClass::valid_cpu_types[]
      hw/arm/vexpress: Check for CPU types in machine_run_board_init()
      hw/arm/zynq: Check for CPU types in machine_run_board_init()

Rayhan Faizel (2):
      hw/ssi: Implement BCM2835 SPI Controller
      hw/arm: Connect SPI Controller to BCM2835

 docs/devel/docs.rst                  |  12 +-
 docs/sphinx/hxtool.py                |  16 +
 docs/system/arm/raspi.rst            |   2 +-
 docs/system/i386/xen.rst             |   3 +-
 include/hw/arm/bcm2835_peripherals.h |   3 +-
 include/hw/arm/msf2-soc.h            |   3 -
 include/hw/arm/npcm7xx.h             |   2 +
 include/hw/net/npcm_gmac.h           | 343 +++++++++++++
 include/hw/qdev-core.h               |   2 -
 include/hw/ssi/bcm2835_spi.h         |  81 +++
 target/arm/syndrome.h                |   8 +
 hw/arm/bcm2835_peripherals.c         |  17 +-
 hw/arm/exynos4210.c                  |   1 +
 hw/arm/exynos4_boards.c              |   8 +
 hw/arm/highbank.c                    |  11 +
 hw/arm/msf2-soc.c                    |   3 +-
 hw/arm/msf2-som.c                    |   4 -
 hw/arm/musca.c                       |   1 -
 hw/arm/npcm7xx.c                     |  37 +-
 hw/arm/npcm7xx_boards.c              |   1 -
 hw/arm/strongarm.c                   |  82 +--
 hw/arm/vexpress.c                    |  12 +-
 hw/arm/xen_arm.c                     |  23 +-
 hw/arm/xilinx_zynq.c                 |   6 +-
 hw/arm/z2.c                          |  27 +-
 hw/core/bus.c                        |  67 ---
 hw/hyperv/vmbus.c                    |   7 +-
 hw/input/adb.c                       |   7 +-
 hw/net/npcm_gmac.c                   | 942 +++++++++++++++++++++++++++++++++++
 hw/pci-host/designware.c             |   2 +
 hw/pci/pci.c                         |  10 +-
 hw/s390x/css-bridge.c                |   5 +-
 hw/ssi/bcm2835_spi.c                 | 288 +++++++++++
 hw/xen/xen-hvm-common.c              |  47 +-
 hw/xen/xen-mapcache.c                |  59 +--
 system/vl.c                          |  22 +-
 target/arm/cpu.c                     |   4 +
 target/arm/helper.c                  |  19 +
 tests/qtest/npcm_gmac-test.c         | 344 +++++++++++++
 tests/qtest/xlnx-versal-trng-test.c  |  19 +-
 tests/tcg/aarch64/sysregs.c          |   2 +-
 hw/arm/Kconfig                       |   1 +
 hw/arm/trace-events                  |  15 +
 hw/net/meson.build                   |   2 +-
 hw/net/trace-events                  |  19 +
 hw/ssi/Kconfig                       |   4 +
 hw/ssi/meson.build                   |   1 +
 hw/xen/trace-events                  |  21 +-
 qemu-options.hx                      |  16 +-
 tests/qtest/meson.build              |   1 +
 50 files changed, 2388 insertions(+), 244 deletions(-)
 create mode 100644 include/hw/net/npcm_gmac.h
 create mode 100644 include/hw/ssi/bcm2835_spi.h
 create mode 100644 hw/net/npcm_gmac.c
 create mode 100644 hw/ssi/bcm2835_spi.c
 create mode 100644 tests/qtest/npcm_gmac-test.c


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

* Re: [PULL 00/36] target-arm queue
  2024-02-02 15:36 Peter Maydell
@ 2024-02-03 13:27 ` Peter Maydell
  0 siblings, 0 replies; 49+ messages in thread
From: Peter Maydell @ 2024-02-03 13:27 UTC (permalink / raw)
  To: qemu-devel

On Fri, 2 Feb 2024 at 15:36, Peter Maydell <peter.maydell@linaro.org> wrote:
>
> The following changes since commit c3709fde5955d13f6d4f86ab46ef3cc2288ca65e:
>
>   Merge tag 'pull-aspeed-20240201' of https://github.com/legoater/qemu into staging (2024-02-01 14:42:11 +0000)
>
> are available in the Git repository at:
>
>   https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240202
>
> for you to fetch changes up to f09c2b7ba9908714a3e2f1decd989462536cf731:
>
>   hw/arm: Connect SPI Controller to BCM2835 (2024-02-02 13:51:59 +0000)
>
> ----------------------------------------------------------------
> target/arm: fix exception syndrome for AArch32 bkpt insn
> pci, vmbus, adb, s390x/css-bridge: Switch buses to 3-phase reset
> system/vl.c: Fix handling of '-serial none -serial something'
> target/arm: Add ID_AA64ZFR0_EL1.B16B16 to the exposed-to-userspace set
> tests/qtest/xlnx-versal-trng-test.c: Drop use of variable length array
> target/arm: Reinstate "vfp" property on AArch32 CPUs
> doc/sphinx/hxtool.py: add optional label argument to SRST directive
> hw/arm: Check for CPU types in machine_run_board_init() for various boards
> pci-host: designware: Limit value range of iATU viewport register
> hw/arm: Convert some DPRINTF macros to trace events and guest errors
> hw/arm: NPCM7XX SoC: Add GMAC ethernet controller devices
> hw/arm: Implement BCM2835 SPI Controller
>


Applied, thanks.

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

-- PMM


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

* [PULL 00/36] target-arm queue
@ 2025-01-28 20:12 Peter Maydell
  2025-01-29 19:17 ` Stefan Hajnoczi
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2025-01-28 20:12 UTC (permalink / raw)
  To: qemu-devel

Hi; here's another arm pullreq; by volume most of this is
refactoring from me, but there are also some bugfixes and
other bits and pieces here.

thanks
-- PMM

The following changes since commit ed734377ab3f3f3cc15d7aa301a87ab6370f2eed:

  Merge tag 'linux-user-fix-gupnp-pull-request' of https://github.com/hdeller/qemu-hppa into staging (2025-01-24 14:43:07 -0500)

are available in the Git repository at:

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

for you to fetch changes up to 664280abddcb3cacc9c6204706bb739fcc1316f7:

  hw/usb/canokey: Fix buffer overflow for OUT packet (2025-01-28 18:40:19 +0000)

----------------------------------------------------------------
target-arm queue:
 * hw/arm: Remove various uses of first_cpu global
 * hw/char/imx_serial: Fix reset value of UFCR register
 * hw/char/imx_serial: Update all state before restarting ageing timer
 * hw/pci-host/designware: Expose MSI IRQ
 * hw/arm/stellaris: refactoring, cleanup
 * hw/arm/stellaris: map both I2C controllers
 * tests/functional: Add a test for the arm microbit machine
 * target/arm: arm_reset_sve_state() should set FPSR, not FPCR
 * target/arm: refactorings preparatory to FEAT_AFP implementation
 * fpu: Rename float_flag_input_denormal to float_flag_input_denormal_flushed
 * fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed
 * hw/usb/canokey: Fix buffer overflow for OUT packet

----------------------------------------------------------------
Bernhard Beschow (3):
      hw/char/imx_serial: Fix reset value of UFCR register
      hw/char/imx_serial: Update all state before restarting ageing timer
      hw/pci-host/designware: Expose MSI IRQ

Hongren Zheng (1):
      hw/usb/canokey: Fix buffer overflow for OUT packet

Peter Maydell (22):
      target/arm: arm_reset_sve_state() should set FPSR, not FPCR
      target/arm: Use FPSR_ constants in vfp_exceptbits_from_host()
      target/arm: Use uint32_t in vfp_exceptbits_from_host()
      target/arm: Define new fp_status_a32 and fp_status_a64
      target/arm: Use vfp.fp_status_a64 in A64-only helper functions
      target/arm: Use fp_status_a64 or fp_status_a32 in is_ebf()
      target/arm: Use fp_status_a32 in vjvct helper
      target/arm: Use fp_status_a32 in vfp_cmp helpers
      target/arm: Use FPST_A32 in A32 decoder
      target/arm: Use FPST_A64 in A64 decoder
      target/arm: Remove now-unused vfp.fp_status and FPST_FPCR
      target/arm: Define new fp_status_f16_a32 and fp_status_f16_a64
      target/arm: Use fp_status_f16_a32 in AArch32-only helpers
      target/arm: Use fp_status_f16_a64 in AArch64-only helpers
      target/arm: Use FPST_A32_F16 in A32 decoder
      target/arm: Use FPST_A64_F16 in A64 decoder
      target/arm: Remove now-unused vfp.fp_status_f16 and FPST_FPCR_F16
      fpu: Rename float_flag_input_denormal to float_flag_input_denormal_flushed
      fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed
      fpu: Fix a comment in softfloat-types.h
      target/arm: Remove redundant advsimd float16 helpers
      target/arm: Use FPST_A64_F16 for halfprec-to-other conversions

Philippe Mathieu-Daudé (9):
      hw/arm/nrf51: Rename ARMv7MState 'cpu' -> 'armv7m'
      hw/arm/stellaris: Add 'armv7m' local variable
      hw/arm/v7m: Remove use of &first_cpu in machine_init()
      hw/arm/stellaris: Link each board schematic
      hw/arm/stellaris: Constify read-only arrays
      hw/arm/stellaris: Remove incorrect unimplemented i2c-0 at 0x40002000
      hw/arm/stellaris: Replace magic numbers by definitions
      hw/arm/stellaris: Use DEVCAP macro to access DeviceCapability registers
      hw/arm/stellaris: Map both I2C controllers

Thomas Huth (1):
      tests/functional: Add a test for the arm microbit machine

 MAINTAINERS                           |   1 +
 hw/usb/canokey.h                      |   4 --
 include/fpu/softfloat-types.h         |  10 +--
 include/hw/arm/fsl-imx6.h             |   4 +-
 include/hw/arm/fsl-imx7.h             |   4 +-
 include/hw/arm/nrf51_soc.h            |   2 +-
 include/hw/char/imx_serial.h          |   2 +-
 include/hw/pci-host/designware.h      |   1 +
 target/arm/cpu.h                      |  12 ++--
 target/arm/tcg/helper-a64.h           |   8 ---
 target/arm/tcg/translate.h            |  32 ++++++---
 fpu/softfloat.c                       |   6 +-
 hw/arm/b-l475e-iot01a.c               |   2 +-
 hw/arm/fsl-imx6.c                     |  13 +++-
 hw/arm/fsl-imx7.c                     |  13 +++-
 hw/arm/microbit.c                     |   2 +-
 hw/arm/mps2-tz.c                      |   2 +-
 hw/arm/mps2.c                         |   2 +-
 hw/arm/msf2-som.c                     |   2 +-
 hw/arm/musca.c                        |   2 +-
 hw/arm/netduino2.c                    |   2 +-
 hw/arm/netduinoplus2.c                |   2 +-
 hw/arm/nrf51_soc.c                    |  18 ++---
 hw/arm/olimex-stm32-h405.c            |   2 +-
 hw/arm/stellaris.c                    | 118 +++++++++++++++++++-----------
 hw/arm/stm32vldiscovery.c             |   2 +-
 hw/char/imx_serial.c                  |   7 +-
 hw/pci-host/designware.c              |   7 +-
 hw/usb/canokey.c                      |   6 +-
 target/arm/cpu.c                      |   6 +-
 target/arm/helper.c                   |   2 +-
 target/arm/tcg/helper-a64.c           |   9 ---
 target/arm/tcg/sme_helper.c           |   6 +-
 target/arm/tcg/sve_helper.c           |   6 +-
 target/arm/tcg/translate-a64.c        | 103 ++++++++++++++-------------
 target/arm/tcg/translate-sme.c        |   4 +-
 target/arm/tcg/translate-sve.c        | 130 +++++++++++++++++-----------------
 target/arm/tcg/translate-vfp.c        |  78 ++++++++++----------
 target/arm/tcg/vec_helper.c           |  22 +++---
 target/arm/vfp_helper.c               |  73 +++++++++++--------
 target/i386/tcg/fpu_helper.c          |   8 +--
 target/m68k/fpu_helper.c              |   2 +-
 target/mips/tcg/msa_helper.c          |   4 +-
 target/rx/op_helper.c                 |   4 +-
 target/tricore/fpu_helper.c           |   6 +-
 fpu/softfloat-parts.c.inc             |   4 +-
 hw/arm/Kconfig                        |   2 +
 tests/functional/meson.build          |   1 +
 tests/functional/test_arm_microbit.py |  31 ++++++++
 49 files changed, 452 insertions(+), 337 deletions(-)
 create mode 100755 tests/functional/test_arm_microbit.py


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

* Re: [PULL 00/36] target-arm queue
  2025-01-28 20:12 Peter Maydell
@ 2025-01-29 19:17 ` Stefan Hajnoczi
  0 siblings, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2025-01-29 19:17 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

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

Applied, thanks.

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* [PULL 00/36] target-arm queue
@ 2025-07-11 13:33 Peter Maydell
  2025-07-13  7:06 ` Stefan Hajnoczi
  0 siblings, 1 reply; 49+ messages in thread
From: Peter Maydell @ 2025-07-11 13:33 UTC (permalink / raw)
  To: qemu-devel

Hi; this should be my last major pullreq before softfreeze: it has
the nested-virt support, a new Cortex-M4 based board model, and
the CXL-on-arm patchset.

thanks
-- PMM

The following changes since commit df6fe2abf2e990f767ce755d426bc439c7bba336:

  Merge tag 'pull-target-arm-20250704' of https://gitlab.com/pm215/qemu into staging (2025-07-07 09:22:41 -0400)

are available in the Git repository at:

  https://gitlab.com/pm215/qemu.git tags/pull-target-arm-20250711

for you to fetch changes up to 3a323a813fd42fc7c37ef09bc7a714d8e31691ce:

  tests/functional: Add a test for the MAX78000 arm machine (2025-07-11 13:30:32 +0100)

----------------------------------------------------------------
target-arm queue:
 * New board type max78000fthr
 * Enable use of CXL on Arm 'virt' board
 * Some more tidyup of ID register handling
 * Refactor AT insns and PMU regs into separate source files
 * Don't enforce NSE,NS check for EL3->EL3 returns
 * hw/arm/fsl-imx8mp: Wire VIRQ and VFIQ
 * Allow nested-virtualization with KVM on the 'virt' board
 * system/qdev: Remove pointless NULL check in qdev_device_add_from_qdict
 * hw/arm/virt-acpi-build: Don't create ITS id mappings by default
 * target/arm: Remove unused helper_sme2_luti4_4b

----------------------------------------------------------------
Bernhard Beschow (1):
      hw/arm/fsl-imx8mp: Wire VIRQ and VFIQ

Cornelia Huck (5):
      arm/cpu: store id_afr0 into the idregs array
      arm/cpu: store id_aa64afr{0,1} into the idregs array
      arm/cpu: fix trailing ',' for SET_IDREG
      arm/cpu: store clidr into the idregs array
      arm/kvm: shorten one overly long line

Eric Auger (1):
      hw/arm/arm_gicv3_kvm: Add a migration blocker with kvm nested virt

Haibo Xu (3):
      hw/arm: Allow setting KVM vGIC maintenance IRQ
      target/arm/kvm: Add helper to detect EL2 when using KVM
      target/arm: Enable feature ARM_FEATURE_EL2 if EL2 is supported

Jackson Donaldson (13):
      MAX78000: Add MAX78000FTHR Machine
      MAX78000: ICC Implementation
      MAX78000: Add ICC to SOC
      MAX78000: UART Implementation
      MAX78000: Add UART to SOC
      MAX78000: GCR Implementation
      MAX78000: Add GCR to SOC
      MAX78000: TRNG Implementation
      MAX78000: Add TRNG to SOC
      MAX78000: AES implementation
      MAX78000: Add AES to SOC
      docs/system: arm: Add max78000 board description
      tests/functional: Add a test for the MAX78000 arm machine

Jonathan Cameron (5):
      hw/cxl-host: Add an index field to CXLFixedMemoryWindow
      hw/cxl: Make the CXL fixed memory windows devices.
      hw/arm/virt: Basic CXL enablement on pci_expander_bridge instances pxb-cxl
      docs/cxl: Add an arm/virt example.
      qtest/cxl: Add aarch64 virt test for CXL

Peter Maydell (2):
      target/arm: Don't enforce NSE,NS check for EL3->EL3 returns
      hw/arm/virt: Allow virt extensions with KVM

Philippe Mathieu-Daudé (1):
      system/qdev: Remove pointless NULL check in qdev_device_add_from_qdict

Richard Henderson (4):
      target/arm: Drop stub for define_tlb_insn_regs
      target/arm: Split out AT insns to tcg/cpregs-at.c
      target/arm: Split out performance monitor regs to cpregs-pmu.c
      target/arm: Remove helper_sme2_luti4_4b

Shameer Kolothum (1):
      hw/arm/virt-acpi-build: Don't create ITS id mappings by default

 docs/system/arm/max78000.rst              |   37 +
 docs/system/arm/virt.rst                  |    9 +
 docs/system/devices/cxl.rst               |   11 +
 docs/system/target-arm.rst                |    1 +
 include/hw/arm/max78000_soc.h             |   50 +
 include/hw/arm/virt.h                     |    4 +
 include/hw/char/max78000_uart.h           |   78 ++
 include/hw/cxl/cxl.h                      |    5 +-
 include/hw/cxl/cxl_host.h                 |    5 +-
 include/hw/intc/arm_gicv3_common.h        |    1 +
 include/hw/misc/max78000_aes.h            |   68 ++
 include/hw/misc/max78000_gcr.h            |  131 +++
 include/hw/misc/max78000_icc.h            |   33 +
 include/hw/misc/max78000_trng.h           |   35 +
 target/arm/cpregs.h                       |    3 +
 target/arm/cpu.h                          |    6 +-
 target/arm/internals.h                    |    5 +
 target/arm/kvm_arm.h                      |    7 +
 target/arm/tcg/helper.h                   |    1 -
 target/arm/cpu-sysregs.h.inc              |    4 +
 hw/acpi/cxl.c                             |   76 +-
 hw/arm/fsl-imx8mp.c                       |    4 +
 hw/arm/max78000_soc.c                     |  232 ++++
 hw/arm/max78000fthr.c                     |   50 +
 hw/arm/virt-acpi-build.c                  |   40 +-
 hw/arm/virt.c                             |   52 +-
 hw/char/max78000_uart.c                   |  285 +++++
 hw/cxl/cxl-host-stubs.c                   |    7 +-
 hw/cxl/cxl-host.c                         |  174 ++-
 hw/i386/pc.c                              |   50 +-
 hw/intc/arm_gicv3_common.c                |    1 +
 hw/intc/arm_gicv3_kvm.c                   |   29 +
 hw/intc/armv7m_nvic.c                     |    4 +-
 hw/misc/max78000_aes.c                    |  223 ++++
 hw/misc/max78000_gcr.c                    |  351 ++++++
 hw/misc/max78000_icc.c                    |  120 ++
 hw/misc/max78000_trng.c                   |  139 +++
 system/qdev-monitor.c                     |    9 +-
 target/arm/cpregs-pmu.c                   | 1309 +++++++++++++++++++++
 target/arm/cpu64.c                        |    8 +-
 target/arm/helper.c                       | 1813 +----------------------------
 target/arm/kvm-stub.c                     |    5 +
 target/arm/kvm.c                          |   24 +-
 target/arm/tcg-stubs.c                    |    5 -
 target/arm/tcg/cpregs-at.c                |  519 +++++++++
 target/arm/tcg/cpu-v7m.c                  |   16 +-
 target/arm/tcg/cpu32.c                    |   34 +-
 target/arm/tcg/cpu64.c                    |   68 +-
 target/arm/tcg/helper-a64.c               |   20 +-
 target/arm/tcg/vec_helper.c               |    1 -
 tests/qtest/cxl-test.c                    |   58 +-
 hw/arm/Kconfig                            |   15 +
 hw/arm/meson.build                        |    2 +
 hw/char/Kconfig                           |    3 +
 hw/char/meson.build                       |    1 +
 hw/misc/Kconfig                           |   12 +
 hw/misc/meson.build                       |    4 +
 target/arm/meson.build                    |    2 +
 target/arm/tcg/meson.build                |    1 +
 tests/functional/meson.build              |    1 +
 tests/functional/test_arm_max78000fthr.py |   48 +
 tests/qtest/meson.build                   |    1 +
 62 files changed, 4300 insertions(+), 2010 deletions(-)
 create mode 100644 docs/system/arm/max78000.rst
 create mode 100644 include/hw/arm/max78000_soc.h
 create mode 100644 include/hw/char/max78000_uart.h
 create mode 100644 include/hw/misc/max78000_aes.h
 create mode 100644 include/hw/misc/max78000_gcr.h
 create mode 100644 include/hw/misc/max78000_icc.h
 create mode 100644 include/hw/misc/max78000_trng.h
 create mode 100644 hw/arm/max78000_soc.c
 create mode 100644 hw/arm/max78000fthr.c
 create mode 100644 hw/char/max78000_uart.c
 create mode 100644 hw/misc/max78000_aes.c
 create mode 100644 hw/misc/max78000_gcr.c
 create mode 100644 hw/misc/max78000_icc.c
 create mode 100644 hw/misc/max78000_trng.c
 create mode 100644 target/arm/cpregs-pmu.c
 create mode 100644 target/arm/tcg/cpregs-at.c
 create mode 100755 tests/functional/test_arm_max78000fthr.py


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

* Re: [PULL 00/36] target-arm queue
  2025-07-11 13:33 Peter Maydell
@ 2025-07-13  7:06 ` Stefan Hajnoczi
  0 siblings, 0 replies; 49+ messages in thread
From: Stefan Hajnoczi @ 2025-07-13  7:06 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

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

Applied, thanks.

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2025-07-13  7:10 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-10 11:47 [PULL 00/36] target-arm queue Peter Maydell
2020-12-10 11:47 ` [PULL 01/36] hw/arm/smmuv3: Fix up L1STD_SPAN decoding Peter Maydell
2020-12-10 11:47 ` [PULL 02/36] hw/net/can: Introduce Xilinx ZynqMP CAN controller Peter Maydell
2020-12-10 11:47 ` [PULL 03/36] xlnx-zynqmp: Connect Xilinx ZynqMP CAN controllers Peter Maydell
2020-12-10 11:47 ` [PULL 04/36] tests/qtest: Introduce tests for Xilinx ZynqMP CAN controller Peter Maydell
2020-12-10 11:47 ` [PULL 05/36] MAINTAINERS: Add maintainer entry " Peter Maydell
2020-12-10 11:47 ` [PULL 06/36] sbsa-ref: allow to use Cortex-A53/57/72 cpus Peter Maydell
2020-12-10 11:47 ` [PULL 07/36] tests/qtest/npcm7xx_rng-test: dump random data on failure Peter Maydell
2020-12-10 11:47 ` [PULL 08/36] i.MX25: Fix bad printf format specifiers Peter Maydell
2020-12-10 11:47 ` [PULL 09/36] i.MX31: " Peter Maydell
2020-12-10 11:47 ` [PULL 10/36] i.MX6: " Peter Maydell
2020-12-10 11:47 ` [PULL 11/36] i.MX6ul: " Peter Maydell
2020-12-10 11:47 ` [PULL 12/36] hw/intc/armv7m_nvic: Make all of system PPB range be RAZWI/BusFault Peter Maydell
2020-12-10 11:47 ` [PULL 13/36] target/arm: Implement v8.1M PXN extension Peter Maydell
2020-12-10 11:47 ` [PULL 14/36] target/arm: Don't clobber ID_PFR1.Security on M-profile cores Peter Maydell
2020-12-10 11:47 ` [PULL 15/36] target/arm: Implement VSCCLRM insn Peter Maydell
2020-12-10 11:47 ` [PULL 16/36] target/arm: Implement CLRM instruction Peter Maydell
2020-12-10 11:47 ` [PULL 17/36] target/arm: Enforce M-profile VMRS/VMSR register restrictions Peter Maydell
2020-12-10 11:47 ` [PULL 18/36] target/arm: Refactor M-profile VMSR/VMRS handling Peter Maydell
2020-12-10 11:47 ` [PULL 19/36] target/arm: Move general-use constant expanders up in translate.c Peter Maydell
2020-12-10 11:47 ` [PULL 20/36] target/arm: Implement VLDR/VSTR system register Peter Maydell
2020-12-10 11:47 ` [PULL 21/36] target/arm: Implement M-profile FPSCR_nzcvqc Peter Maydell
2020-12-10 11:47 ` [PULL 22/36] target/arm: Use new FPCR_NZCV_MASK constant Peter Maydell
2020-12-10 11:47 ` [PULL 23/36] target/arm: Factor out preserve-fp-state from full_vfp_access_check() Peter Maydell
2020-12-10 11:47 ` [PULL 24/36] target/arm: Implement FPCXT_S fp system register Peter Maydell
2020-12-10 11:47 ` [PULL 25/36] hw/intc/armv7m_nvic: Update FPDSCR masking for v8.1M Peter Maydell
2020-12-10 11:47 ` [PULL 26/36] target/arm: For v8.1M, always clear R0-R3, R12, APSR, EPSR on exception entry Peter Maydell
2020-12-10 11:47 ` [PULL 27/36] target/arm: In v8.1M, don't set HFSR.FORCED on vector table fetch failures Peter Maydell
2020-12-10 11:47 ` [PULL 28/36] target/arm: Implement v8.1M REVIDR register Peter Maydell
2020-12-10 11:47 ` [PULL 29/36] target/arm: Implement new v8.1M NOCP check for exception return Peter Maydell
2020-12-10 11:47 ` [PULL 30/36] target/arm: Implement new v8.1M VLLDM and VLSTM encodings Peter Maydell
2020-12-10 11:47 ` [PULL 31/36] hw/intc/armv7m_nvic: Support v8.1M CCR.TRD bit Peter Maydell
2020-12-10 11:47 ` [PULL 32/36] target/arm: Implement CCR_S.TRD behaviour for SG insns Peter Maydell
2020-12-10 11:47 ` [PULL 33/36] hw/intc/armv7m_nvic: Fix "return from inactive handler" check Peter Maydell
2020-12-10 11:47 ` [PULL 34/36] target/arm: Implement M-profile "minimal RAS implementation" Peter Maydell
2020-12-10 11:47 ` [PULL 35/36] hw/intc/armv7m_nvic: Implement read/write for RAS register block Peter Maydell
2020-12-10 11:47 ` [PULL 36/36] hw/arm/armv7m: Correct typo in QOM object name Peter Maydell
2020-12-10 12:51 ` [PULL 00/36] target-arm queue Peter Maydell
  -- strict thread matches above, loose matches on Subject: below --
2025-07-11 13:33 Peter Maydell
2025-07-13  7:06 ` Stefan Hajnoczi
2025-01-28 20:12 Peter Maydell
2025-01-29 19:17 ` Stefan Hajnoczi
2024-02-02 15:36 Peter Maydell
2024-02-03 13:27 ` Peter Maydell
2024-01-26 14:33 Peter Maydell
2024-01-27 13:00 ` Peter Maydell
2020-09-14 14:06 Peter Maydell
2020-03-12 16:44 Peter Maydell
2020-03-12 20:32 ` Peter Maydell

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