Re: [PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-17 Thread Damien Hedde



On 8/17/21 10:25 AM, Luc Michel wrote:
> On 10:33 Thu 12 Aug , Peter Maydell wrote:
>> Currently we implement the RAS register block within the NVIC device.
>> It isn't really very tightly coupled with the NVIC proper, so instead
>> move it out into a sysbus device of its own and have the top level
>> ARMv7M container create it and map it into memory at the right
>> address.
>>
>> Signed-off-by: Peter Maydell 
> 
> Reviewed-by: Luc Michel 

Reviewed-by: Damien Hedde 
> 
>> ---
>>  include/hw/arm/armv7m.h   |  2 +
>>  include/hw/intc/armv7m_nvic.h |  1 -
>>  include/hw/misc/armv7m_ras.h  | 37 ++
>>  hw/arm/armv7m.c   | 12 +
>>  hw/intc/armv7m_nvic.c | 56 -
>>  hw/misc/armv7m_ras.c  | 93 +++
>>  MAINTAINERS   |  2 +
>>  hw/misc/meson.build   |  2 +
>>  8 files changed, 148 insertions(+), 57 deletions(-)
>>  create mode 100644 include/hw/misc/armv7m_ras.h
>>  create mode 100644 hw/misc/armv7m_ras.c
>>
>> diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
>> index bc6733c5184..4cae0d7eeaa 100644
>> --- a/include/hw/arm/armv7m.h
>> +++ b/include/hw/arm/armv7m.h
>> @@ -12,6 +12,7 @@
>>  
>>  #include "hw/sysbus.h"
>>  #include "hw/intc/armv7m_nvic.h"
>> +#include "hw/misc/armv7m_ras.h"
>>  #include "target/arm/idau.h"
>>  #include "qom/object.h"
>>  
>> @@ -58,6 +59,7 @@ struct ARMv7MState {
>>  NVICState nvic;
>>  BitBandState bitband[ARMV7M_NUM_BITBANDS];
>>  ARMCPU *cpu;
>> +ARMv7MRAS ras;
>>  
>>  /* MemoryRegion we pass to the CPU, with our devices layered on
>>   * top of the ones the board provides in board_memory.
>> diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
>> index 39c71e15936..33b6d8810c7 100644
>> --- a/include/hw/intc/armv7m_nvic.h
>> +++ b/include/hw/intc/armv7m_nvic.h
>> @@ -83,7 +83,6 @@ struct NVICState {
>>  MemoryRegion sysreg_ns_mem;
>>  MemoryRegion systickmem;
>>  MemoryRegion systick_ns_mem;
>> -MemoryRegion ras_mem;
>>  MemoryRegion container;
>>  MemoryRegion defaultmem;
>>  
>> diff --git a/include/hw/misc/armv7m_ras.h b/include/hw/misc/armv7m_ras.h
>> new file mode 100644
>> index 000..f8773e65b14
>> --- /dev/null
>> +++ b/include/hw/misc/armv7m_ras.h
>> @@ -0,0 +1,37 @@
>> +/*
>> + * Arm M-profile RAS block
>> + *
>> + * Copyright (c) 2021 Linaro Limited
>> + *
>> + *  This program is free software; you can redistribute it and/or modify
>> + *  it under the terms of the GNU General Public License version 2 or
>> + *  (at your option) any later version.
>> + */
>> +
>> +/*
>> + * This is a model of the RAS register block of an M-profile CPU
>> + * (the registers starting at 0xE0005000 with ERRFRn).
>> + *
>> + * QEMU interface:
>> + *  + sysbus MMIO region 0: the register bank
>> + *
>> + * The QEMU implementation currently provides "minimal RAS" only.
>> + */
>> +
>> +#ifndef HW_MISC_ARMV7M_RAS_H
>> +#define HW_MISC_ARMV7M_RAS_H
>> +
>> +#include "hw/sysbus.h"
>> +
>> +#define TYPE_ARMV7M_RAS "armv7m-ras"
>> +OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MRAS, ARMV7M_RAS)
>> +
>> +struct ARMv7MRAS {
>> +/*< private >*/
>> +SysBusDevice parent_obj;
>> +
>> +/*< public >*/
>> +MemoryRegion iomem;
>> +};
>> +
>> +#endif
>> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
>> index 9ce5c30cd5c..8964730d153 100644
>> --- a/hw/arm/armv7m.c
>> +++ b/hw/arm/armv7m.c
>> @@ -231,6 +231,18 @@ static void armv7m_realize(DeviceState *dev, Error 
>> **errp)
>>  memory_region_add_subregion(>container, 0xe000,
>>  sysbus_mmio_get_region(sbd, 0));
>>  
>> +/* If the CPU has RAS support, create the RAS register block */
>> +if (cpu_isar_feature(aa32_ras, s->cpu)) {
>> +object_initialize_child(OBJECT(dev), "armv7m-ras",
>> +>ras, TYPE_ARMV7M_RAS);
>> +sbd = SYS_BUS_DEVICE(>ras);
>> +if (!sysbus_realize(sbd, errp)) {
>> +return;
>> +}
>> +memory_region_add_subregion_overlap(>container, 0xe0005000,
>> +sysbus_mmio_get_region(sbd, 0), 
>> 1);
>> +}
>> +
>>  for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
>>  if (s->enable_bitband) {
>>  Object *obj = OBJECT(>bitband[i]);
>> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
>> index 1e7ddcb94cb..a5975592dfa 100644
>> --- a/hw/intc/armv7m_nvic.c
>> +++ b/hw/intc/armv7m_nvic.c
>> @@ -2549,56 +2549,6 @@ 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 */
>> -  

Re: [PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-17 Thread Luc Michel
On 10:33 Thu 12 Aug , Peter Maydell wrote:
> Currently we implement the RAS register block within the NVIC device.
> It isn't really very tightly coupled with the NVIC proper, so instead
> move it out into a sysbus device of its own and have the top level
> ARMv7M container create it and map it into memory at the right
> address.
> 
> Signed-off-by: Peter Maydell 

Reviewed-by: Luc Michel 

> ---
>  include/hw/arm/armv7m.h   |  2 +
>  include/hw/intc/armv7m_nvic.h |  1 -
>  include/hw/misc/armv7m_ras.h  | 37 ++
>  hw/arm/armv7m.c   | 12 +
>  hw/intc/armv7m_nvic.c | 56 -
>  hw/misc/armv7m_ras.c  | 93 +++
>  MAINTAINERS   |  2 +
>  hw/misc/meson.build   |  2 +
>  8 files changed, 148 insertions(+), 57 deletions(-)
>  create mode 100644 include/hw/misc/armv7m_ras.h
>  create mode 100644 hw/misc/armv7m_ras.c
> 
> diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
> index bc6733c5184..4cae0d7eeaa 100644
> --- a/include/hw/arm/armv7m.h
> +++ b/include/hw/arm/armv7m.h
> @@ -12,6 +12,7 @@
>  
>  #include "hw/sysbus.h"
>  #include "hw/intc/armv7m_nvic.h"
> +#include "hw/misc/armv7m_ras.h"
>  #include "target/arm/idau.h"
>  #include "qom/object.h"
>  
> @@ -58,6 +59,7 @@ struct ARMv7MState {
>  NVICState nvic;
>  BitBandState bitband[ARMV7M_NUM_BITBANDS];
>  ARMCPU *cpu;
> +ARMv7MRAS ras;
>  
>  /* MemoryRegion we pass to the CPU, with our devices layered on
>   * top of the ones the board provides in board_memory.
> diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
> index 39c71e15936..33b6d8810c7 100644
> --- a/include/hw/intc/armv7m_nvic.h
> +++ b/include/hw/intc/armv7m_nvic.h
> @@ -83,7 +83,6 @@ struct NVICState {
>  MemoryRegion sysreg_ns_mem;
>  MemoryRegion systickmem;
>  MemoryRegion systick_ns_mem;
> -MemoryRegion ras_mem;
>  MemoryRegion container;
>  MemoryRegion defaultmem;
>  
> diff --git a/include/hw/misc/armv7m_ras.h b/include/hw/misc/armv7m_ras.h
> new file mode 100644
> index 000..f8773e65b14
> --- /dev/null
> +++ b/include/hw/misc/armv7m_ras.h
> @@ -0,0 +1,37 @@
> +/*
> + * Arm M-profile RAS block
> + *
> + * Copyright (c) 2021 Linaro Limited
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 or
> + *  (at your option) any later version.
> + */
> +
> +/*
> + * This is a model of the RAS register block of an M-profile CPU
> + * (the registers starting at 0xE0005000 with ERRFRn).
> + *
> + * QEMU interface:
> + *  + sysbus MMIO region 0: the register bank
> + *
> + * The QEMU implementation currently provides "minimal RAS" only.
> + */
> +
> +#ifndef HW_MISC_ARMV7M_RAS_H
> +#define HW_MISC_ARMV7M_RAS_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_ARMV7M_RAS "armv7m-ras"
> +OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MRAS, ARMV7M_RAS)
> +
> +struct ARMv7MRAS {
> +/*< private >*/
> +SysBusDevice parent_obj;
> +
> +/*< public >*/
> +MemoryRegion iomem;
> +};
> +
> +#endif
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index 9ce5c30cd5c..8964730d153 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -231,6 +231,18 @@ static void armv7m_realize(DeviceState *dev, Error 
> **errp)
>  memory_region_add_subregion(>container, 0xe000,
>  sysbus_mmio_get_region(sbd, 0));
>  
> +/* If the CPU has RAS support, create the RAS register block */
> +if (cpu_isar_feature(aa32_ras, s->cpu)) {
> +object_initialize_child(OBJECT(dev), "armv7m-ras",
> +>ras, TYPE_ARMV7M_RAS);
> +sbd = SYS_BUS_DEVICE(>ras);
> +if (!sysbus_realize(sbd, errp)) {
> +return;
> +}
> +memory_region_add_subregion_overlap(>container, 0xe0005000,
> +sysbus_mmio_get_region(sbd, 0), 
> 1);
> +}
> +
>  for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
>  if (s->enable_bitband) {
>  Object *obj = OBJECT(>bitband[i]);
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index 1e7ddcb94cb..a5975592dfa 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -2549,56 +2549,6 @@ 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 */
> -

Re: [PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-16 Thread Peter Maydell
On Sun, 15 Aug 2021 at 18:30, Philippe Mathieu-Daudé  wrote:
>
> +Peter/David
>
> On 8/12/21 11:33 AM, Peter Maydell wrote:
> > Currently we implement the RAS register block within the NVIC device.
> > It isn't really very tightly coupled with the NVIC proper, so instead
> > move it out into a sysbus device of its own and have the top level
> > ARMv7M container create it and map it into memory at the right
> > address.
> >
> > Signed-off-by: Peter Maydell 
> > ---
> >  include/hw/arm/armv7m.h   |  2 +
> >  include/hw/intc/armv7m_nvic.h |  1 -
> >  include/hw/misc/armv7m_ras.h  | 37 ++
> >  hw/arm/armv7m.c   | 12 +
> >  hw/intc/armv7m_nvic.c | 56 -
> >  hw/misc/armv7m_ras.c  | 93 +++
> >  MAINTAINERS   |  2 +
> >  hw/misc/meson.build   |  2 +
> >  8 files changed, 148 insertions(+), 57 deletions(-)
> >  create mode 100644 include/hw/misc/armv7m_ras.h
> >  create mode 100644 hw/misc/armv7m_ras.c
>
> > diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> > index 9ce5c30cd5c..8964730d153 100644
> > --- a/hw/arm/armv7m.c
> > +++ b/hw/arm/armv7m.c
> > @@ -231,6 +231,18 @@ static void armv7m_realize(DeviceState *dev, Error 
> > **errp)
> >  memory_region_add_subregion(>container, 0xe000,
> >  sysbus_mmio_get_region(sbd, 0));
> >
> > +/* If the CPU has RAS support, create the RAS register block */
> > +if (cpu_isar_feature(aa32_ras, s->cpu)) {
> > +object_initialize_child(OBJECT(dev), "armv7m-ras",
> > +>ras, TYPE_ARMV7M_RAS);
> > +sbd = SYS_BUS_DEVICE(>ras);
> > +if (!sysbus_realize(sbd, errp)) {
> > +return;
> > +}
> > +memory_region_add_subregion_overlap(>container, 0xe0005000,
> > +sysbus_mmio_get_region(sbd, 
> > 0), 1);
>
> Just curious, is the overlap really needed?

Yes, because this block is currently in the middle of the
PPB-area region provided by the NVIC, and needs to take priority
over it. Once the refactoring is complete, the background-region
will also be created in this armv7m realize function, but the
RAS block still needs to go above it.

> I see the NVIC default
> region is 1 MiB wide. Aren't smaller regions returned first when
> multiple regions have same priority?

As David says, if you don't specify the priority then it's
pot-luck which one you see. Having overlaps and not setting
priorities is a QEMU bug. (We used to have some code to print
a warning about unintentionally overlapping regions, but it was
always disabled with #if 0 and we eventually deleted it in commit
b61359781958. IIRC the reason we never enabled either a warning
or an assertion was because for the PC machine's PCI devices
in particular we thought it might be possible for the guest to
map PCI devices at a silly address and generate overlaps, but
I may well have the details wrong as it was years back.)

-- PMM



Re: [PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-16 Thread David Hildenbrand

On 15.08.21 19:30, Philippe Mathieu-Daudé wrote:

+Peter/David

On 8/12/21 11:33 AM, Peter Maydell wrote:

Currently we implement the RAS register block within the NVIC device.
It isn't really very tightly coupled with the NVIC proper, so instead
move it out into a sysbus device of its own and have the top level
ARMv7M container create it and map it into memory at the right
address.

Signed-off-by: Peter Maydell 
---
  include/hw/arm/armv7m.h   |  2 +
  include/hw/intc/armv7m_nvic.h |  1 -
  include/hw/misc/armv7m_ras.h  | 37 ++
  hw/arm/armv7m.c   | 12 +
  hw/intc/armv7m_nvic.c | 56 -
  hw/misc/armv7m_ras.c  | 93 +++
  MAINTAINERS   |  2 +
  hw/misc/meson.build   |  2 +
  8 files changed, 148 insertions(+), 57 deletions(-)
  create mode 100644 include/hw/misc/armv7m_ras.h
  create mode 100644 hw/misc/armv7m_ras.c



diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 9ce5c30cd5c..8964730d153 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -231,6 +231,18 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
  memory_region_add_subregion(>container, 0xe000,
  sysbus_mmio_get_region(sbd, 0));
  
+/* If the CPU has RAS support, create the RAS register block */

+if (cpu_isar_feature(aa32_ras, s->cpu)) {
+object_initialize_child(OBJECT(dev), "armv7m-ras",
+>ras, TYPE_ARMV7M_RAS);
+sbd = SYS_BUS_DEVICE(>ras);
+if (!sysbus_realize(sbd, errp)) {
+return;
+}
+memory_region_add_subregion_overlap(>container, 0xe0005000,
+sysbus_mmio_get_region(sbd, 0), 1);


Just curious, is the overlap really needed? I see the NVIC default
region is 1 MiB wide. Aren't smaller regions returned first when
multiple regions have same priority? This might be one of my
misunderstandings with QEMU MR/AS APIs. Without looking at the
code, assuming 2 MRs overlapping with the same priority, is there
some assumption which one will be hit first?



memory_region_add_subregion() documents "The subregion may not overlap 
with other subregions", however it really just translates to adding with 
priority 0.


memory_region_add_subregion_overlap documents "The subregion may overlap 
with other subregions.  Conflicts are resolved by having a higher 
@priority hide a lower @priority. Subregions without priority are taken 
as @priority 0 ... highest priority wins"


AFAIU, overlaps with same priority (e.g., 0) have undefined behavior and 
we should really be using memory_region_add_subregion_overlap() with 
proper priorities.



+}
+
  for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
  if (s->enable_bitband) {
  Object *obj = OBJECT(>bitband[i]);





--
Thanks,

David / dhildenb




Re: [PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-15 Thread Philippe Mathieu-Daudé
+Peter/David

On 8/12/21 11:33 AM, Peter Maydell wrote:
> Currently we implement the RAS register block within the NVIC device.
> It isn't really very tightly coupled with the NVIC proper, so instead
> move it out into a sysbus device of its own and have the top level
> ARMv7M container create it and map it into memory at the right
> address.
> 
> Signed-off-by: Peter Maydell 
> ---
>  include/hw/arm/armv7m.h   |  2 +
>  include/hw/intc/armv7m_nvic.h |  1 -
>  include/hw/misc/armv7m_ras.h  | 37 ++
>  hw/arm/armv7m.c   | 12 +
>  hw/intc/armv7m_nvic.c | 56 -
>  hw/misc/armv7m_ras.c  | 93 +++
>  MAINTAINERS   |  2 +
>  hw/misc/meson.build   |  2 +
>  8 files changed, 148 insertions(+), 57 deletions(-)
>  create mode 100644 include/hw/misc/armv7m_ras.h
>  create mode 100644 hw/misc/armv7m_ras.c

> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index 9ce5c30cd5c..8964730d153 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -231,6 +231,18 @@ static void armv7m_realize(DeviceState *dev, Error 
> **errp)
>  memory_region_add_subregion(>container, 0xe000,
>  sysbus_mmio_get_region(sbd, 0));
>  
> +/* If the CPU has RAS support, create the RAS register block */
> +if (cpu_isar_feature(aa32_ras, s->cpu)) {
> +object_initialize_child(OBJECT(dev), "armv7m-ras",
> +>ras, TYPE_ARMV7M_RAS);
> +sbd = SYS_BUS_DEVICE(>ras);
> +if (!sysbus_realize(sbd, errp)) {
> +return;
> +}
> +memory_region_add_subregion_overlap(>container, 0xe0005000,
> +sysbus_mmio_get_region(sbd, 0), 
> 1);

Just curious, is the overlap really needed? I see the NVIC default
region is 1 MiB wide. Aren't smaller regions returned first when
multiple regions have same priority? This might be one of my
misunderstandings with QEMU MR/AS APIs. Without looking at the
code, assuming 2 MRs overlapping with the same priority, is there
some assumption which one will be hit first?

> +}
> +
>  for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
>  if (s->enable_bitband) {
>  Object *obj = OBJECT(>bitband[i]);



Re: [PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-12 Thread Alistair Francis
On Thu, Aug 12, 2021 at 7:34 PM Peter Maydell  wrote:
>
> Currently we implement the RAS register block within the NVIC device.
> It isn't really very tightly coupled with the NVIC proper, so instead
> move it out into a sysbus device of its own and have the top level
> ARMv7M container create it and map it into memory at the right
> address.
>
> Signed-off-by: Peter Maydell 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/hw/arm/armv7m.h   |  2 +
>  include/hw/intc/armv7m_nvic.h |  1 -
>  include/hw/misc/armv7m_ras.h  | 37 ++
>  hw/arm/armv7m.c   | 12 +
>  hw/intc/armv7m_nvic.c | 56 -
>  hw/misc/armv7m_ras.c  | 93 +++
>  MAINTAINERS   |  2 +
>  hw/misc/meson.build   |  2 +
>  8 files changed, 148 insertions(+), 57 deletions(-)
>  create mode 100644 include/hw/misc/armv7m_ras.h
>  create mode 100644 hw/misc/armv7m_ras.c
>
> diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
> index bc6733c5184..4cae0d7eeaa 100644
> --- a/include/hw/arm/armv7m.h
> +++ b/include/hw/arm/armv7m.h
> @@ -12,6 +12,7 @@
>
>  #include "hw/sysbus.h"
>  #include "hw/intc/armv7m_nvic.h"
> +#include "hw/misc/armv7m_ras.h"
>  #include "target/arm/idau.h"
>  #include "qom/object.h"
>
> @@ -58,6 +59,7 @@ struct ARMv7MState {
>  NVICState nvic;
>  BitBandState bitband[ARMV7M_NUM_BITBANDS];
>  ARMCPU *cpu;
> +ARMv7MRAS ras;
>
>  /* MemoryRegion we pass to the CPU, with our devices layered on
>   * top of the ones the board provides in board_memory.
> diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
> index 39c71e15936..33b6d8810c7 100644
> --- a/include/hw/intc/armv7m_nvic.h
> +++ b/include/hw/intc/armv7m_nvic.h
> @@ -83,7 +83,6 @@ struct NVICState {
>  MemoryRegion sysreg_ns_mem;
>  MemoryRegion systickmem;
>  MemoryRegion systick_ns_mem;
> -MemoryRegion ras_mem;
>  MemoryRegion container;
>  MemoryRegion defaultmem;
>
> diff --git a/include/hw/misc/armv7m_ras.h b/include/hw/misc/armv7m_ras.h
> new file mode 100644
> index 000..f8773e65b14
> --- /dev/null
> +++ b/include/hw/misc/armv7m_ras.h
> @@ -0,0 +1,37 @@
> +/*
> + * Arm M-profile RAS block
> + *
> + * Copyright (c) 2021 Linaro Limited
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 or
> + *  (at your option) any later version.
> + */
> +
> +/*
> + * This is a model of the RAS register block of an M-profile CPU
> + * (the registers starting at 0xE0005000 with ERRFRn).
> + *
> + * QEMU interface:
> + *  + sysbus MMIO region 0: the register bank
> + *
> + * The QEMU implementation currently provides "minimal RAS" only.
> + */
> +
> +#ifndef HW_MISC_ARMV7M_RAS_H
> +#define HW_MISC_ARMV7M_RAS_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_ARMV7M_RAS "armv7m-ras"
> +OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MRAS, ARMV7M_RAS)
> +
> +struct ARMv7MRAS {
> +/*< private >*/
> +SysBusDevice parent_obj;
> +
> +/*< public >*/
> +MemoryRegion iomem;
> +};
> +
> +#endif
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index 9ce5c30cd5c..8964730d153 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -231,6 +231,18 @@ static void armv7m_realize(DeviceState *dev, Error 
> **errp)
>  memory_region_add_subregion(>container, 0xe000,
>  sysbus_mmio_get_region(sbd, 0));
>
> +/* If the CPU has RAS support, create the RAS register block */
> +if (cpu_isar_feature(aa32_ras, s->cpu)) {
> +object_initialize_child(OBJECT(dev), "armv7m-ras",
> +>ras, TYPE_ARMV7M_RAS);
> +sbd = SYS_BUS_DEVICE(>ras);
> +if (!sysbus_realize(sbd, errp)) {
> +return;
> +}
> +memory_region_add_subregion_overlap(>container, 0xe0005000,
> +sysbus_mmio_get_region(sbd, 0), 
> 1);
> +}
> +
>  for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
>  if (s->enable_bitband) {
>  Object *obj = OBJECT(>bitband[i]);
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index 1e7ddcb94cb..a5975592dfa 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -2549,56 +2549,6 @@ 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 */
> 

Re: [PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-12 Thread Peter Maydell
On Thu, 12 Aug 2021 at 12:08, Alexandre IOOSS  wrote:
>
>
>
> On 8/12/21 11:33 AM, Peter Maydell wrote:
> > Currently we implement the RAS register block within the NVIC device.
> > It isn't really very tightly coupled with the NVIC proper, so instead
> > move it out into a sysbus device of its own and have the top level
> > ARMv7M container create it and map it into memory at the right
> > address.
> >
> > Signed-off-by: Peter Maydell 
> > ---
> >   include/hw/arm/armv7m.h   |  2 +
> >   include/hw/intc/armv7m_nvic.h |  1 -
> >   include/hw/misc/armv7m_ras.h  | 37 ++
> >   hw/arm/armv7m.c   | 12 +
> >   hw/intc/armv7m_nvic.c | 56 -
> >   hw/misc/armv7m_ras.c  | 93 +++
> >   MAINTAINERS   |  2 +
> >   hw/misc/meson.build   |  2 +
> >   8 files changed, 148 insertions(+), 57 deletions(-)
> >   create mode 100644 include/hw/misc/armv7m_ras.h
> >   create mode 100644 hw/misc/armv7m_ras.c
> >
> > diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
> > index bc6733c5184..4cae0d7eeaa 100644
> > --- a/include/hw/arm/armv7m.h
> > +++ b/include/hw/arm/armv7m.h
> > @@ -12,6 +12,7 @@
> >
> >   #include "hw/sysbus.h"
> >   #include "hw/intc/armv7m_nvic.h"
> > +#include "hw/misc/armv7m_ras.h"
> >   #include "target/arm/idau.h"
> >   #include "qom/object.h"
> >
> > @@ -58,6 +59,7 @@ struct ARMv7MState {
> >   NVICState nvic;
> >   BitBandState bitband[ARMV7M_NUM_BITBANDS];
> >   ARMCPU *cpu;
> > +ARMv7MRAS ras;
> >
> >   /* MemoryRegion we pass to the CPU, with our devices layered on
> >* top of the ones the board provides in board_memory.
> > diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
> > index 39c71e15936..33b6d8810c7 100644
> > --- a/include/hw/intc/armv7m_nvic.h
> > +++ b/include/hw/intc/armv7m_nvic.h
> > @@ -83,7 +83,6 @@ struct NVICState {
> >   MemoryRegion sysreg_ns_mem;
> >   MemoryRegion systickmem;
> >   MemoryRegion systick_ns_mem;
> > -MemoryRegion ras_mem;
> >   MemoryRegion container;
> >   MemoryRegion defaultmem;
> >
> > diff --git a/include/hw/misc/armv7m_ras.h b/include/hw/misc/armv7m_ras.h
> > new file mode 100644
> > index 000..f8773e65b14
> > --- /dev/null
> > +++ b/include/hw/misc/armv7m_ras.h
> > @@ -0,0 +1,37 @@
> > +/*
> > + * Arm M-profile RAS block
> > + *
> > + * Copyright (c) 2021 Linaro Limited
> > + *
> > + *  This program is free software; you can redistribute it and/or modify
> > + *  it under the terms of the GNU General Public License version 2 or
> > + *  (at your option) any later version.
> > + */
>
> Maybe it would be a good idea here to change to "Arm M-profile RAS
> (Reliability, Availability, and Serviceability) block" to define the
> acronym at least once in the device code?

Yeah, we could perhaps put a comment in there somewhere.
Though really you need to look in the spec to understand
what the block is doing, at which point you'll find out what
the register block is for.

> > +static void armv7m_ras_class_init(ObjectClass *klass, void *data)
> > +{
> > +/* This device has no state: no need for vmstate or reset */
> > +}
> > +
> > +static const TypeInfo armv7m_ras_info = {
> > +.name = TYPE_ARMV7M_RAS,
> > +.parent = TYPE_SYS_BUS_DEVICE,
> > +.instance_size = sizeof(ARMv7MRAS),
> > +.instance_init = armv7m_ras_init,
> > +.class_init = armv7m_ras_class_init,
> > +};
>
> Pure curiosity: is `.class_init` defined because it needs to be defined
> or is it only a good practise in QEMU code to always define it?

It's optional, and in this case it's only there because it makes
a place to put the comment, I guess.

-- PMM



Re: [PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-12 Thread Alexandre IOOSS



On 8/12/21 11:33 AM, Peter Maydell wrote:

Currently we implement the RAS register block within the NVIC device.
It isn't really very tightly coupled with the NVIC proper, so instead
move it out into a sysbus device of its own and have the top level
ARMv7M container create it and map it into memory at the right
address.

Signed-off-by: Peter Maydell 
---
  include/hw/arm/armv7m.h   |  2 +
  include/hw/intc/armv7m_nvic.h |  1 -
  include/hw/misc/armv7m_ras.h  | 37 ++
  hw/arm/armv7m.c   | 12 +
  hw/intc/armv7m_nvic.c | 56 -
  hw/misc/armv7m_ras.c  | 93 +++
  MAINTAINERS   |  2 +
  hw/misc/meson.build   |  2 +
  8 files changed, 148 insertions(+), 57 deletions(-)
  create mode 100644 include/hw/misc/armv7m_ras.h
  create mode 100644 hw/misc/armv7m_ras.c

diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
index bc6733c5184..4cae0d7eeaa 100644
--- a/include/hw/arm/armv7m.h
+++ b/include/hw/arm/armv7m.h
@@ -12,6 +12,7 @@
  
  #include "hw/sysbus.h"

  #include "hw/intc/armv7m_nvic.h"
+#include "hw/misc/armv7m_ras.h"
  #include "target/arm/idau.h"
  #include "qom/object.h"
  
@@ -58,6 +59,7 @@ struct ARMv7MState {

  NVICState nvic;
  BitBandState bitband[ARMV7M_NUM_BITBANDS];
  ARMCPU *cpu;
+ARMv7MRAS ras;
  
  /* MemoryRegion we pass to the CPU, with our devices layered on

   * top of the ones the board provides in board_memory.
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index 39c71e15936..33b6d8810c7 100644
--- a/include/hw/intc/armv7m_nvic.h
+++ b/include/hw/intc/armv7m_nvic.h
@@ -83,7 +83,6 @@ struct NVICState {
  MemoryRegion sysreg_ns_mem;
  MemoryRegion systickmem;
  MemoryRegion systick_ns_mem;
-MemoryRegion ras_mem;
  MemoryRegion container;
  MemoryRegion defaultmem;
  
diff --git a/include/hw/misc/armv7m_ras.h b/include/hw/misc/armv7m_ras.h

new file mode 100644
index 000..f8773e65b14
--- /dev/null
+++ b/include/hw/misc/armv7m_ras.h
@@ -0,0 +1,37 @@
+/*
+ * Arm M-profile RAS block
+ *
+ * Copyright (c) 2021 Linaro Limited
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */


Maybe it would be a good idea here to change to "Arm M-profile RAS 
(Reliability, Availability, and Serviceability) block" to define the 
acronym at least once in the device code?



+
+/*
+ * This is a model of the RAS register block of an M-profile CPU
+ * (the registers starting at 0xE0005000 with ERRFRn).
+ *
+ * QEMU interface:
+ *  + sysbus MMIO region 0: the register bank
+ *
+ * The QEMU implementation currently provides "minimal RAS" only.
+ */
+
+#ifndef HW_MISC_ARMV7M_RAS_H
+#define HW_MISC_ARMV7M_RAS_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ARMV7M_RAS "armv7m-ras"
+OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MRAS, ARMV7M_RAS)
+
+struct ARMv7MRAS {
+/*< private >*/
+SysBusDevice parent_obj;
+
+/*< public >*/
+MemoryRegion iomem;
+};
+
+#endif
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 9ce5c30cd5c..8964730d153 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -231,6 +231,18 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
  memory_region_add_subregion(>container, 0xe000,
  sysbus_mmio_get_region(sbd, 0));
  
+/* If the CPU has RAS support, create the RAS register block */

+if (cpu_isar_feature(aa32_ras, s->cpu)) {
+object_initialize_child(OBJECT(dev), "armv7m-ras",
+>ras, TYPE_ARMV7M_RAS);
+sbd = SYS_BUS_DEVICE(>ras);
+if (!sysbus_realize(sbd, errp)) {
+return;
+}
+memory_region_add_subregion_overlap(>container, 0xe0005000,
+sysbus_mmio_get_region(sbd, 0), 1);
+}
+
  for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
  if (s->enable_bitband) {
  Object *obj = OBJECT(>bitband[i]);
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 1e7ddcb94cb..a5975592dfa 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2549,56 +2549,6 @@ 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 

[PATCH for-6.2 01/25] arm: Move M-profile RAS register block into its own device

2021-08-12 Thread Peter Maydell
Currently we implement the RAS register block within the NVIC device.
It isn't really very tightly coupled with the NVIC proper, so instead
move it out into a sysbus device of its own and have the top level
ARMv7M container create it and map it into memory at the right
address.

Signed-off-by: Peter Maydell 
---
 include/hw/arm/armv7m.h   |  2 +
 include/hw/intc/armv7m_nvic.h |  1 -
 include/hw/misc/armv7m_ras.h  | 37 ++
 hw/arm/armv7m.c   | 12 +
 hw/intc/armv7m_nvic.c | 56 -
 hw/misc/armv7m_ras.c  | 93 +++
 MAINTAINERS   |  2 +
 hw/misc/meson.build   |  2 +
 8 files changed, 148 insertions(+), 57 deletions(-)
 create mode 100644 include/hw/misc/armv7m_ras.h
 create mode 100644 hw/misc/armv7m_ras.c

diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
index bc6733c5184..4cae0d7eeaa 100644
--- a/include/hw/arm/armv7m.h
+++ b/include/hw/arm/armv7m.h
@@ -12,6 +12,7 @@
 
 #include "hw/sysbus.h"
 #include "hw/intc/armv7m_nvic.h"
+#include "hw/misc/armv7m_ras.h"
 #include "target/arm/idau.h"
 #include "qom/object.h"
 
@@ -58,6 +59,7 @@ struct ARMv7MState {
 NVICState nvic;
 BitBandState bitband[ARMV7M_NUM_BITBANDS];
 ARMCPU *cpu;
+ARMv7MRAS ras;
 
 /* MemoryRegion we pass to the CPU, with our devices layered on
  * top of the ones the board provides in board_memory.
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
index 39c71e15936..33b6d8810c7 100644
--- a/include/hw/intc/armv7m_nvic.h
+++ b/include/hw/intc/armv7m_nvic.h
@@ -83,7 +83,6 @@ struct NVICState {
 MemoryRegion sysreg_ns_mem;
 MemoryRegion systickmem;
 MemoryRegion systick_ns_mem;
-MemoryRegion ras_mem;
 MemoryRegion container;
 MemoryRegion defaultmem;
 
diff --git a/include/hw/misc/armv7m_ras.h b/include/hw/misc/armv7m_ras.h
new file mode 100644
index 000..f8773e65b14
--- /dev/null
+++ b/include/hw/misc/armv7m_ras.h
@@ -0,0 +1,37 @@
+/*
+ * Arm M-profile RAS block
+ *
+ * Copyright (c) 2021 Linaro Limited
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 or
+ *  (at your option) any later version.
+ */
+
+/*
+ * This is a model of the RAS register block of an M-profile CPU
+ * (the registers starting at 0xE0005000 with ERRFRn).
+ *
+ * QEMU interface:
+ *  + sysbus MMIO region 0: the register bank
+ *
+ * The QEMU implementation currently provides "minimal RAS" only.
+ */
+
+#ifndef HW_MISC_ARMV7M_RAS_H
+#define HW_MISC_ARMV7M_RAS_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ARMV7M_RAS "armv7m-ras"
+OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MRAS, ARMV7M_RAS)
+
+struct ARMv7MRAS {
+/*< private >*/
+SysBusDevice parent_obj;
+
+/*< public >*/
+MemoryRegion iomem;
+};
+
+#endif
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 9ce5c30cd5c..8964730d153 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -231,6 +231,18 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
 memory_region_add_subregion(>container, 0xe000,
 sysbus_mmio_get_region(sbd, 0));
 
+/* If the CPU has RAS support, create the RAS register block */
+if (cpu_isar_feature(aa32_ras, s->cpu)) {
+object_initialize_child(OBJECT(dev), "armv7m-ras",
+>ras, TYPE_ARMV7M_RAS);
+sbd = SYS_BUS_DEVICE(>ras);
+if (!sysbus_realize(sbd, errp)) {
+return;
+}
+memory_region_add_subregion_overlap(>container, 0xe0005000,
+sysbus_mmio_get_region(sbd, 0), 1);
+}
+
 for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
 if (s->enable_bitband) {
 Object *obj = OBJECT(>bitband[i]);
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 1e7ddcb94cb..a5975592dfa 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2549,56 +2549,6 @@ 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,
-