Re: [q] Status of IOMMU virtualization for nested virtualization (userspace PCI drivers in VMs)

2024-02-29 Thread Peter Delevoryas



> On Feb 28, 2024, at 11:38 AM, Alex Williamson  
> wrote:
> 
> On Wed, 28 Feb 2024 10:29:32 -0800
> Peter Delevoryas  wrote:
> 
>> Hey guys,
>> 
>> I’m having a little trouble reading between the lines on various
>> docs, mailing list threads, KVM presentations, github forks, etc, so
>> I figured I’d just ask:
>> 
>> What is the status of IOMMU virtualization, like in the case where I
>> want a VM guest to have a virtual IOMMU?
> 
> It works fine for simply nested assignment scenarios, ie. guest
> userspace drivers or nested VMs.
> 
>> I found this great presentation from KVM Forum 2021: [1]
>> 
>> 1. I’m using -device intel-iommu right now. This has performance
>> implications and large DMA transfers hit the vfio_iommu_type1
>> dma_entry_limit on the host because of how the mappings are made.
> 
> Hugepages for the guest and mappings within the guest should help both
> the mapping performance and DMA entry limit.  In general the type1 vfio
> IOMMU backend is not optimized for dynamic mapping, so performance-wise
> your best bet is still to design the userspace driver for static DMA
> buffers.

Yep, huge pages definitely help, will probably switch to allocating them at 
boot for better guarantees.

> 
>> 2. -device virtio-iommu is an improvement, but it doesn’t seem
>> compatible with -device vfio-pci? I was only able to test this with
>> cloud-hypervisor, and it has a better vfio mapping pattern (avoids
>> hitting dma_entry_limit).
> 
> AFAIK it's just growing pains, it should work but it's working through
> bugs.

Oh really?? Ok: I might even be configuring things incorrectly, or
Maybe I need to upgrade from QEMU 7.1 to 8. I was relying on whatever
libvirt does by default, which seems to just be:

-device virtio-iommu -device vfio-pci,host=

But maybe I need some other options?

> 
>> 3. -object iommufd [2] I haven’t tried this quite yet, planning to:
>> if it’s using iommufd, and I have all the right kernel features in
>> the guest and host, I assume it’s implementing the passthrough mode
>> that AMD has described in their talk? Because I imagine that would be
>> the best solution for me, I’m just having trouble understanding if
>> it’s actually related or orthogonal.
> 
> For now iommufd provides a similar DMA mapping interface to type1, but
> it does remove the DMA entry limit and improves locked page accounting.
> 
> To really see a performance improvement relative to dynamic mappings,
> you'll need nesting support in the IOMMU, which is under active
> development.  From this aspect you will want iommufd since similar
> features will not be provided by type1.  Thanks,

I see, thanks! That’s great to hear.

> 
> Alex
> 




[q] Status of IOMMU virtualization for nested virtualization (userspace PCI drivers in VMs)

2024-02-28 Thread Peter Delevoryas
Hey guys,

I’m having a little trouble reading between the lines on various docs, mailing 
list threads, KVM presentations, github forks, etc, so I figured I’d just ask:

What is the status of IOMMU virtualization, like in the case where I want a VM 
guest to have a virtual IOMMU?

I found this great presentation from KVM Forum 2021: [1]

1. I’m using -device intel-iommu right now. This has performance implications 
and large DMA transfers hit the vfio_iommu_type1 dma_entry_limit on the host 
because of how the mappings are made.

2. -device virtio-iommu is an improvement, but it doesn’t seem compatible with 
-device vfio-pci? I was only able to test this with cloud-hypervisor, and it 
has a better vfio mapping pattern (avoids hitting dma_entry_limit).

3. -object iommufd [2] I haven’t tried this quite yet, planning to: if it’s 
using iommufd, and I have all the right kernel features in the guest and host, 
I assume it’s implementing the passthrough mode that AMD has described in their 
talk? Because I imagine that would be the best solution for me, I’m just having 
trouble understanding if it’s actually related or orthogonal. I see AMD has 
-device amd-viommu here [3], is that ever going to be upstreamed or is that 
what -object iommufd is abstracting? I also found this mailing list submission 
[4], and the context and changes there imply this is all about that (exposing 
iommu virtualization to the guest)

Thanks!
Peter
 
[1] 
https://static.sched.com/hosted_files/kvmforum2021/da/vIOMMU%20KVM%20Forum%202021%20-%20v4.pdf
[2] https://www.qemu.org/docs/master/devel/vfio-iommufd.html
[3] 
https://github.com/AMDESE/qemu/commit/ee056455c411ee3369a47c65ba8a54783b5d2814
[4] 
https://lore.kernel.org/lkml/20230621235508.113949-1-suravee.suthikulpa...@amd.com/




Re: [PULL 4/5] contrib/gitdm: Add Facebook the domain map

2023-03-10 Thread Peter Delevoryas



> On Mar 10, 2023, at 7:57 AM, Alex Bennée  wrote:
> 
> A number of Facebook developers contribute to the project. Peter can
> you confirm your want pjd.dev contributions counted here or as
> an individual contributor?

I want them counted as Facebook, for now. If I leave Facebook I’ll send an 
update 

Thanks!
Peter

> 
> Signed-off-by: Alex Bennée 
> Cc: Iris Chen 
> Cc: Daniel Müller 
> Reviewed-by: Peter Delevoryas 
> Message-Id: <20221219121914.851488-9-alex.ben...@linaro.org>
> 
> diff --git a/contrib/gitdm/domain-map b/contrib/gitdm/domain-map
> index 1ea20b9890..8913a886c9 100644
> --- a/contrib/gitdm/domain-map
> +++ b/contrib/gitdm/domain-map
> @@ -12,6 +12,7 @@ citrix.com  Citrix
> crudebyte.com   Crudebyte
> chinatelecom.cn China Telecom
> eldorado.org.br Instituto de Pesquisas Eldorado
> +fb.com  Facebook
> fujitsu.com Fujitsu
> google.com  Google
> greensocs.com   GreenSocs
> diff --git a/contrib/gitdm/group-map-facebook 
> b/contrib/gitdm/group-map-facebook
> new file mode 100644
> index 00..38589f8fb9
> --- /dev/null
> +++ b/contrib/gitdm/group-map-facebook
> @@ -0,0 +1,5 @@
> +#
> +# Some Facebook contributors also occasionally use personal email addresses.
> +#
> +
> +pe...@pjd.dev
> diff --git a/gitdm.config b/gitdm.config
> index 288b100d89..907ffde017 100644
> --- a/gitdm.config
> +++ b/gitdm.config
> @@ -33,6 +33,7 @@ EmailMap contrib/gitdm/domain-map
> 
> GroupMap contrib/gitdm/group-map-cadence Cadence Design Systems
> GroupMap contrib/gitdm/group-map-codeweavers CodeWeavers
> +GroupMap contrib/gitdm/group-map-facebook Facebook
> GroupMap contrib/gitdm/group-map-ibm IBM
> GroupMap contrib/gitdm/group-map-janustech Janus Technologies
> GroupMap contrib/gitdm/group-map-netflix Netflix
> -- 
> 2.39.2
> 




Re: [PATCH qemu v3 2/2] aspeed/fuji : correct the eeprom size

2023-02-27 Thread Peter Delevoryas
On Fri, Feb 17, 2023 at 09:59:53AM +0700, ~ssinprem wrote:
> From: Sittisak Sinprem 
> 
> Device 24C64 the size is 64 kilobits = 8kilobyte
> Device 24C02 the size is 2 kilobits = 256byte
> 
> Signed-off-by: Sittisak Sinprem 
> ---
>  hw/arm/aspeed.c | 36 
>  1 file changed, 20 insertions(+), 16 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 27dda58338..40f6076b44 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -840,42 +840,46 @@ static void fuji_bmc_i2c_init(AspeedMachineState *bmc)
>  i2c_slave_create_simple(i2c[17], TYPE_LM75, 0x4c);
>  i2c_slave_create_simple(i2c[17], TYPE_LM75, 0x4d);
>  
> -at24c_eeprom_init(i2c[19], 0x52, 64 * KiB);
> -at24c_eeprom_init(i2c[20], 0x50, 2 * KiB);
> -at24c_eeprom_init(i2c[22], 0x52, 2 * KiB);
> +/*
> +* EEPROM 24c64 size is 64Kbits or 8 Kbytes
> +*24c02 size is 2Kbits or 256 bytes
> +*/
> +at24c_eeprom_init(i2c[19], 0x52, 8 * KiB);
> +at24c_eeprom_init(i2c[20], 0x50, 256);
> +    at24c_eeprom_init(i2c[22], 0x52, 256);

Perfect! Looks good.

Reviewed-by: Peter Delevoryas 

>  
>  i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x48);
>  i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x49);
>  i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x4a);
>  i2c_slave_create_simple(i2c[3], TYPE_TMP422, 0x4c);
>  
> -at24c_eeprom_init(i2c[8], 0x51, 64 * KiB);
> +at24c_eeprom_init(i2c[8], 0x51, 8 * KiB);
>  i2c_slave_create_simple(i2c[8], TYPE_LM75, 0x4a);
>  
>  i2c_slave_create_simple(i2c[50], TYPE_LM75, 0x4c);
> -at24c_eeprom_init(i2c[50], 0x52, 64 * KiB);
> +at24c_eeprom_init(i2c[50], 0x52, 8 * KiB);
>  i2c_slave_create_simple(i2c[51], TYPE_TMP75, 0x48);
>  i2c_slave_create_simple(i2c[52], TYPE_TMP75, 0x49);
>  
>  i2c_slave_create_simple(i2c[59], TYPE_TMP75, 0x48);
>  i2c_slave_create_simple(i2c[60], TYPE_TMP75, 0x49);
>  
> -at24c_eeprom_init(i2c[65], 0x53, 64 * KiB);
> +at24c_eeprom_init(i2c[65], 0x53, 8 * KiB);
>  i2c_slave_create_simple(i2c[66], TYPE_TMP75, 0x49);
>  i2c_slave_create_simple(i2c[66], TYPE_TMP75, 0x48);
> -at24c_eeprom_init(i2c[68], 0x52, 64 * KiB);
> -at24c_eeprom_init(i2c[69], 0x52, 64 * KiB);
> -at24c_eeprom_init(i2c[70], 0x52, 64 * KiB);
> -at24c_eeprom_init(i2c[71], 0x52, 64 * KiB);
> +at24c_eeprom_init(i2c[68], 0x52, 8 * KiB);
> +at24c_eeprom_init(i2c[69], 0x52, 8 * KiB);
> +at24c_eeprom_init(i2c[70], 0x52, 8 * KiB);
> +at24c_eeprom_init(i2c[71], 0x52, 8 * KiB);
>  
> -at24c_eeprom_init(i2c[73], 0x53, 64 * KiB);
> +at24c_eeprom_init(i2c[73], 0x53, 8 * KiB);
>  i2c_slave_create_simple(i2c[74], TYPE_TMP75, 0x49);
>  i2c_slave_create_simple(i2c[74], TYPE_TMP75, 0x48);
> -at24c_eeprom_init(i2c[76], 0x52, 64 * KiB);
> -at24c_eeprom_init(i2c[77], 0x52, 64 * KiB);
> -at24c_eeprom_init(i2c[78], 0x52, 64 * KiB);
> -at24c_eeprom_init(i2c[79], 0x52, 64 * KiB);
> -at24c_eeprom_init(i2c[28], 0x50, 2 * KiB);
> +at24c_eeprom_init(i2c[76], 0x52, 8 * KiB);
> +at24c_eeprom_init(i2c[77], 0x52, 8 * KiB);
> +at24c_eeprom_init(i2c[78], 0x52, 8 * KiB);
> +at24c_eeprom_init(i2c[79], 0x52, 8 * KiB);
> +at24c_eeprom_init(i2c[28], 0x50, 256);
>  
>  for (int i = 0; i < 8; i++) {
>  at24c_eeprom_init(i2c[81 + i * 8], 0x56, 64 * KiB);
> -- 
> 2.34.6
> 



Re: [PATCH qemu v3 1/2] hw/at24c : modify at24c to support 1 byte address mode

2023-02-27 Thread Peter Delevoryas
On Fri, Feb 17, 2023 at 10:31:27AM +0700, ~ssinprem wrote:
> From: Sittisak Sinprem 
> 
> Signed-off-by: Sittisak Sinprem 
> ---
>  hw/nvram/eeprom_at24c.c | 28 +---
>  1 file changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> index 3328c32814..64259cde67 100644
> --- a/hw/nvram/eeprom_at24c.c
> +++ b/hw/nvram/eeprom_at24c.c
> @@ -41,6 +41,12 @@ struct EEPROMState {
>  uint16_t cur;
>  /* total size in bytes */
>  uint32_t rsize;
> +/* address byte number 
> + *  for  24c01, 24c02 size <= 256 byte, use only 1 byte
> + *  otherwise size > 256, use 2 byte
> + */
> +uint8_t asize;

I was going to say "why not address_size", but then I see right above there's
"rsize", which is also very obscure lol, so whatever, this is keeping
consistent with the existing code.

> +
>  bool writable;
>  /* cells changed since last START? */
>  bool changed;
> @@ -91,7 +97,10 @@ uint8_t at24c_eeprom_recv(I2CSlave *s)
>  EEPROMState *ee = AT24C_EE(s);
>  uint8_t ret;
>  
> -if (ee->haveaddr == 1) {
> +/* If got the byte address but not completely with address size
> + *  will return the invalid value
> + */
> +if (ee->haveaddr > 0 && ee->haveaddr < ee->asize) {
>  return 0xff;
>  }
>  
> @@ -108,11 +117,11 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
>  {
>  EEPROMState *ee = AT24C_EE(s);
>  
> -if (ee->haveaddr < 2) {
> +if (ee->haveaddr < ee->asize) {

Yay, love it 

>  ee->cur <<= 8;
>  ee->cur |= data;
>  ee->haveaddr++;
> -if (ee->haveaddr == 2) {
> +if (ee->haveaddr == ee->asize) {
>  ee->cur %= ee->rsize;
>  DPRINTK("Set pointer %04x\n", ee->cur);
>  }
> @@ -199,6 +208,18 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
> **errp)
>  }
>  DPRINTK("Reset read backing file\n");
>  }
> +
> +/*
> + * If address size didn't define with property set
> + *   value is 0 as default, setting it by Rom size detecting.

Helpful comment, good stuff

> + */
> +if (ee->asize == 0) {
> +if (ee->rsize <= 256) {
> +ee->asize = 1;
> +} else {
> +ee->asize = 2;
> +}
> +}
>  }
>  
>  static
> @@ -213,6 +234,7 @@ void at24c_eeprom_reset(DeviceState *state)
>  
>  static Property at24c_eeprom_props[] = {
>  DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
> +DEFINE_PROP_UINT8("address-size", EEPROMState, asize, 0),
>  DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
>  DEFINE_PROP_DRIVE("drive", EEPROMState, blk),
>  DEFINE_PROP_END_OF_LIST()

Reviewed-by: Peter Delevoryas 

> -- 
> 2.34.6
> 
> 



Re: [PATCH qemu 1/2] hw/at24c : modify at24c to support 1 byte address mode

2023-02-15 Thread Peter Delevoryas
On Tue, Feb 14, 2023 at 03:29:33PM +0100, Cédric Le Goater wrote:
> On 2/10/23 07:20, ~ssinprem wrote:
> > From: Sittisak Sinprem 
> 
> 
> 
> You will need to add a Signed-off-by tag
> 
> Thanks,
> 
> C.

Oh, yeah this is a pretty good change: I mean, at first I had no idea what's
going on here, so it would be nice if we could leave a comment or refactor it
to be simpler.

Maybe instead of if-statements for > 256 or <= 256, we could do an address size
attribute and compute the 256 bound from the address size.

Anyways, this is a really small change to fix behavior, we can do a refactoring
like that later (If Cedric is ok with it).

Reviewed-by: Peter Delevoryas 

> 
> > ---
> >   hw/nvram/eeprom_at24c.c | 8 +---
> >   1 file changed, 5 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> > index 2d4d8b952f..693212b661 100644
> > --- a/hw/nvram/eeprom_at24c.c
> > +++ b/hw/nvram/eeprom_at24c.c
> > @@ -87,7 +87,7 @@ uint8_t at24c_eeprom_recv(I2CSlave *s)
> >   EEPROMState *ee = AT24C_EE(s);
> >   uint8_t ret;
> > -if (ee->haveaddr == 1) {
> > +if (ee->rsize > 256 && ee->haveaddr == 1) {
> >   return 0xff;
> >   }
> > @@ -104,11 +104,13 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
> >   {
> >   EEPROMState *ee = AT24C_EE(s);
> > -if (ee->haveaddr < 2) {
> > +if ((ee->rsize > 256 && ee->haveaddr < 2) ||
> > +(ee->rsize <= 256 && ee->haveaddr < 1)) {
> >   ee->cur <<= 8;
> >   ee->cur |= data;
> >   ee->haveaddr++;
> > -if (ee->haveaddr == 2) {
> > +if ((ee->rsize > 256 && ee->haveaddr == 2) ||
> > +(ee->rsize <= 256 && ee->haveaddr == 1)) {
> >   ee->cur %= ee->rsize;
> >   DPRINTK("Set pointer %04x\n", ee->cur);
> >   }
> 



Re: [PATCH qemu 2/2] aspeed/fuji : correct the eeprom size

2023-02-15 Thread Peter Delevoryas
On Tue, Feb 14, 2023 at 03:28:58PM +0100, Cédric Le Goater wrote:
> Hello,
> 
> Adding Peter since he contributed the fuji machine,
> 
> On 2/14/23 10:06, ~ssinprem wrote:
> > From: Sittisak Sinprem 
> > 
> > Device 24C64 the size is 64 kilobits
> > Device 24C02 the size is 2 kilobits
> 
> Could you please specify the size in bytes ?
> 
> You will need to add a Signed-off-by tag.
> 
> Thanks,
> 
> C.

Thanks Cedric,

Sittisak, thanks for this fix, I didn't realize the size was in bits (oops lol,
I'm pretty new to embedded systems)

I agree with Cedric though, instead of adding "/ 8", could we just replace 64 *
KiB / 8 with 8 * KiB, and 2 * KiB / 8 with 256?

- Peter

Reviewed-by: Peter Delevoryas 

> 
> > ---
> >   hw/arm/aspeed.c | 32 
> >   1 file changed, 16 insertions(+), 16 deletions(-)
> > 
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > index 55f114ef72..8e6a1579e4 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -846,42 +846,42 @@ static void fuji_bmc_i2c_init(AspeedMachineState *bmc)
> >   i2c_slave_create_simple(i2c[17], TYPE_LM75, 0x4c);
> >   i2c_slave_create_simple(i2c[17], TYPE_LM75, 0x4d);
> > -aspeed_eeprom_init(i2c[19], 0x52, 64 * KiB);
> > -aspeed_eeprom_init(i2c[20], 0x50, 2 * KiB);
> > -aspeed_eeprom_init(i2c[22], 0x52, 2 * KiB);
> > +aspeed_eeprom_init(i2c[19], 0x52, 64 * KiB / 8);
> > +aspeed_eeprom_init(i2c[20], 0x50, 2 * KiB / 8);
> > +aspeed_eeprom_init(i2c[22], 0x52, 2 * KiB / 8);
> >   i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x48);
> >   i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x49);
> >   i2c_slave_create_simple(i2c[3], TYPE_LM75, 0x4a);
> >   i2c_slave_create_simple(i2c[3], TYPE_TMP422, 0x4c);
> > -aspeed_eeprom_init(i2c[8], 0x51, 64 * KiB);
> > +aspeed_eeprom_init(i2c[8], 0x51, 64 * KiB / 8);
> >   i2c_slave_create_simple(i2c[8], TYPE_LM75, 0x4a);
> >   i2c_slave_create_simple(i2c[50], TYPE_LM75, 0x4c);
> > -aspeed_eeprom_init(i2c[50], 0x52, 64 * KiB);
> > +aspeed_eeprom_init(i2c[50], 0x52, 64 * KiB / 8);
> >   i2c_slave_create_simple(i2c[51], TYPE_TMP75, 0x48);
> >   i2c_slave_create_simple(i2c[52], TYPE_TMP75, 0x49);
> >   i2c_slave_create_simple(i2c[59], TYPE_TMP75, 0x48);
> >   i2c_slave_create_simple(i2c[60], TYPE_TMP75, 0x49);
> > -aspeed_eeprom_init(i2c[65], 0x53, 64 * KiB);
> > +aspeed_eeprom_init(i2c[65], 0x53, 64 * KiB / 8);
> >   i2c_slave_create_simple(i2c[66], TYPE_TMP75, 0x49);
> >   i2c_slave_create_simple(i2c[66], TYPE_TMP75, 0x48);
> > -aspeed_eeprom_init(i2c[68], 0x52, 64 * KiB);
> > -aspeed_eeprom_init(i2c[69], 0x52, 64 * KiB);
> > -aspeed_eeprom_init(i2c[70], 0x52, 64 * KiB);
> > -aspeed_eeprom_init(i2c[71], 0x52, 64 * KiB);
> > +aspeed_eeprom_init(i2c[68], 0x52, 64 * KiB / 8);
> > +aspeed_eeprom_init(i2c[69], 0x52, 64 * KiB / 8);
> > +aspeed_eeprom_init(i2c[70], 0x52, 64 * KiB / 8);
> > +aspeed_eeprom_init(i2c[71], 0x52, 64 * KiB / 8);
> > -aspeed_eeprom_init(i2c[73], 0x53, 64 * KiB);
> > +aspeed_eeprom_init(i2c[73], 0x53, 64 * KiB / 8);
> >   i2c_slave_create_simple(i2c[74], TYPE_TMP75, 0x49);
> >   i2c_slave_create_simple(i2c[74], TYPE_TMP75, 0x48);
> > -aspeed_eeprom_init(i2c[76], 0x52, 64 * KiB);
> > -aspeed_eeprom_init(i2c[77], 0x52, 64 * KiB);
> > -aspeed_eeprom_init(i2c[78], 0x52, 64 * KiB);
> > -aspeed_eeprom_init(i2c[79], 0x52, 64 * KiB);
> > -aspeed_eeprom_init(i2c[28], 0x50, 2 * KiB);
> > +aspeed_eeprom_init(i2c[76], 0x52, 64 * KiB / 8);
> > +aspeed_eeprom_init(i2c[77], 0x52, 64 * KiB / 8);
> > +aspeed_eeprom_init(i2c[78], 0x52, 64 * KiB / 8);
> > +aspeed_eeprom_init(i2c[79], 0x52, 64 * KiB / 8);
> > +aspeed_eeprom_init(i2c[28], 0x50, 2 * KiB / 8);
> >   for (int i = 0; i < 8; i++) {
> >   aspeed_eeprom_init(i2c[81 + i * 8], 0x56, 64 * KiB);
> 



Re: [PATCH 1/8] m25p80: Improve error when the backend file size does not match the device

2023-02-15 Thread Peter Delevoryas
On Tue, Feb 14, 2023 at 06:18:23PM +0100, Cédric Le Goater wrote:
> Currently, when a block backend is attached to a m25p80 device and the
> associated file size does not match the flash model, QEMU complains
> with the error message "failed to read the initial flash content".
> This is confusing for the user.
> 
> Use blk_check_size_and_read_all() instead of blk_pread() to improve
> the reported error.
> 
> Reviewed-by: Peter Maydell 
> Reviewed-by: Philippe Mathieu-Daudé 
> Reviewed-by: Peter Delevoryas 
> Reviewed-by: Alistair Francis 
> Message-Id: <20221115151000.2080833-1-...@kaod.org>
> Signed-off-by: Cédric Le Goater 
> ---
> 
>   breakage with commit a4b15a8b9e ("pflash: Only read non-zero parts
>   of backend image") when using -snaphot.


I guess it's not obvious to me, what broke?

1. BlockBackend *blk = -drive file=blob.mtd,format=raw,if=mtd,snapshot=on
2. uint8_t *storage = malloc(...)
3. blk_check_size_and_read_all(blk, storage, size)
4. commit a4b15a8b9e 
for sector in blk:
if any(b != 0 for b in sector):
memcpy([...], sector, sizeof(sector))
else:
# Skip memcpy of zeroes

But this is probably a regression for us because we actually expect the zeroes
to be copied?

- Peter

> 
>  hw/block/m25p80.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 802d2eb021..dc5ffbc4ff 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -24,6 +24,7 @@
>  #include "qemu/osdep.h"
>  #include "qemu/units.h"
>  #include "sysemu/block-backend.h"
> +#include "hw/block/block.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/qdev-properties-system.h"
>  #include "hw/ssi/ssi.h"
> @@ -1615,8 +1616,7 @@ static void m25p80_realize(SSIPeripheral *ss, Error 
> **errp)
>  trace_m25p80_binding(s);
>  s->storage = blk_blockalign(s->blk, s->size);
>  
> -if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
> -error_setg(errp, "failed to read the initial flash content");
> +if (!blk_check_size_and_read_all(s->blk, s->storage, s->size, errp)) 
> {
>  return;
>  }
>  } else {
> -- 
> 2.39.1
> 



[PATCH v5 0/5] hw/nvram/eeprom_at24c: Cleanup + FRUID EEPROM init example

2023-01-27 Thread Peter Delevoryas
v1: https://lore.kernel.org/qemu-devel/20230114170151.87833-1-pe...@pjd.dev/
v2:
- Squashed 3 commits from original series into extract helper commit
- Dropped last 2 commits from original series
- Changed at24c_eeprom_init to return the I2CSlave object
- Added commit to introduce at24c-eeprom "init_rom" attribute
- Added aspeed_eeprom.c and fby35-bmc BMC FRUID EEPROM initialization
- Added commit to change reset behavior for at24c-eeprom (optional)
v3:
- Added doc comments to function headers
- Added fby35 NIC and baseboard EEPROM's (to illustrate 2+ EEPROM's)
- Replaced "extern uint32 fby35_bmc_fruid_size" by adding explicit array
  sizes, e.g. "extern uint8_t fby35_bmc_fruid[200]".
- Fixed Meta Platforms licenses by adding SPDX-License-Identifier for GPL2.
- Moved ee->init_rom initialization code before ee->blk, so that -drive
  property overrides init_rom initialization. This gives more flexibility
  (people can override contents of an AT24C EEPROM using a file for
  debugging/prototyping) while still allowing the init_rom data to be
  specified for a board for default behavior.
v4:
- Moved at24c_eeprom_init_rom doc comment to the patch introducing the
  function (moved from patch 4/5 to patch 3/5).
- Added review tags from Joel
v5:
- Added review tags from Corey
- Added tested-by tag from Ninad
- Switched back to i2c_slave_new in eeprom_at24c.c
- Switched back to "extern const size_t fby35_*_len" in aspeed_eeprom.h

NOTE: I rebased on the latest master and tlb exec segfaults in "Starting
kernel" for fby35-bmc: I'll make a bug report separately. I've kept the base on
7c9236d6d61f because of this.

Thanks,
Peter

Peter Delevoryas (5):
  hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton
boards
  hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init
  hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom
helper
  hw/arm/aspeed: Add aspeed_eeprom.c
  hw/nvram/eeprom_at24c: Make reset behavior more like hardware

 hw/arm/aspeed.c | 109 ++--
 hw/arm/aspeed_eeprom.c  |  82 
 hw/arm/aspeed_eeprom.h  |  19 ++
 hw/arm/meson.build  |   1 +
 hw/arm/npcm7xx_boards.c |  20 ++
 hw/nvram/eeprom_at24c.c |  58 +
 include/hw/nvram/eeprom_at24c.h |  39 
 7 files changed, 241 insertions(+), 87 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h
 create mode 100644 include/hw/nvram/eeprom_at24c.h

-- 
2.39.0




[PATCH v5 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-27 Thread Peter Delevoryas
Allows users to specify binary data to initialize an EEPROM, allowing users to
emulate data programmed at manufacturing time.

- Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
- Added at24c_eeprom_init_rom helper function to initialize attributes
- If -drive property is provided, it overrides init_rom data

Signed-off-by: Peter Delevoryas 
Reviewed-by: Joel Stanley 
Reviewed-by: Corey Minyard 
Reviewed-by: Cédric Le Goater 
Tested-by: Ninad Palsule 
---
 hw/nvram/eeprom_at24c.c | 36 -
 include/hw/nvram/eeprom_at24c.h | 16 +++
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 98857e3626b9..05598699dc2b 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -50,6 +50,9 @@ struct EEPROMState {
 uint8_t *mem;
 
 BlockBackend *blk;
+
+const uint8_t *init_rom;
+uint32_t init_rom_size;
 };
 
 static
@@ -131,19 +134,37 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
 {
-I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
-DeviceState *dev = DEVICE(i2c_dev);
+return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
+}
+
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size)
+{
+EEPROMState *s;
+
+s = AT24C_EE(i2c_slave_new(TYPE_AT24C_EE, address));
+
+qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
 
-qdev_prop_set_uint32(dev, "rom-size", rom_size);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+/* TODO: Model init_rom with QOM properties. */
+s->init_rom = init_rom;
+s->init_rom_size = init_rom_size;
 
-return i2c_dev;
+i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
+
+return I2C_SLAVE(s);
 }
 
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
 
+if (ee->init_rom_size > ee->rsize) {
+error_setg(errp, "%s: init rom is larger than rom: %u > %u",
+   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
+return;
+}
+
 if (ee->blk) {
 int64_t len = blk_getlength(ee->blk);
 
@@ -163,6 +184,7 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
+
 }
 
 static
@@ -176,6 +198,10 @@ void at24c_eeprom_reset(DeviceState *state)
 
 memset(ee->mem, 0, ee->rsize);
 
+if (ee->init_rom) {
+memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
+}
+
 if (ee->blk) {
 int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
 
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
index 196db309d451..acb9857b2add 100644
--- a/include/hw/nvram/eeprom_at24c.h
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -20,4 +20,20 @@
  */
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
 
+
+/*
+ * Create and realize an AT24C EEPROM device on the heap with initial data.
+ * @bus: I2C bus to put it on
+ * @address: I2C address of the EEPROM slave when put on a bus
+ * @rom_size: size of the EEPROM
+ * @init_rom: Array of bytes to initialize EEPROM memory with
+ * @init_rom_size: Size of @init_rom, must be less than or equal to @rom_size
+ *
+ * Create the device state structure, initialize it, put it on the specified
+ * @bus, and drop the reference to it (the device is realized). Copies the data
+ * from @init_rom to the beginning of the EEPROM memory buffer.
+ */
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size);
+
 #endif
-- 
2.39.0




[PATCH v5 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-27 Thread Peter Delevoryas
EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
I would expect the I2C state machine to be reset to default values, but I
wouldn't really expect the memory to change at all.

The current implementation of the at24c EEPROM resets its internal memory on
reset. This matches the specification in docs/devel/reset.rst:

  Cold reset is supported by every resettable object. In QEMU, it means we reset
  to the initial state corresponding to the start of QEMU; this might differ
  from what is a real hardware cold reset. It differs from other resets (like
  warm or bus resets) which may keep certain parts untouched.

But differs from my intuition. For example, if someone writes some information
to an EEPROM, then AC power cycles their board, they would expect the EEPROM to
retain that information. It's very useful to be able to test things like this
in QEMU as well, to verify software instrumentation like determining the cause
of a reboot.

Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
Signed-off-by: Peter Delevoryas 
Reviewed-by: Joel Stanley 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Corey Minyard 
---
 hw/nvram/eeprom_at24c.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 05598699dc2b..3328c3281435 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -184,18 +184,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
-
-}
-
-static
-void at24c_eeprom_reset(DeviceState *state)
-{
-EEPROMState *ee = AT24C_EE(state);
-
-ee->changed = false;
-ee->cur = 0;
-ee->haveaddr = 0;
-
 memset(ee->mem, 0, ee->rsize);
 
 if (ee->init_rom) {
@@ -213,6 +201,16 @@ void at24c_eeprom_reset(DeviceState *state)
 }
 }
 
+static
+void at24c_eeprom_reset(DeviceState *state)
+{
+EEPROMState *ee = AT24C_EE(state);
+
+ee->changed = false;
+ee->cur = 0;
+ee->haveaddr = 0;
+}
+
 static Property at24c_eeprom_props[] = {
 DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
 DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
-- 
2.39.0




[PATCH v5 2/5] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-27 Thread Peter Delevoryas
aspeed_eeprom_init is an exact copy of at24c_eeprom_init, not needed.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Joel Stanley 
Reviewed-by: Corey Minyard 
---
 hw/arm/aspeed.c | 95 ++---
 1 file changed, 43 insertions(+), 52 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1f9799d4321e..c929c61d582a 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
   eeprom_buf);
 }
 
-static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
@@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 AspeedSoCState *soc = >soc;
 I2CSlave *i2c_mux;
 
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
 
 create_pca9552(soc, 3, 0x61);
 
@@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4a);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
 create_pca9552(soc, 4, 0x60);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), TYPE_TMP105,
@@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 create_pca9552(soc, 5, 0x61);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6), TYPE_TMP105,
  0x48);
@@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4b);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
 
 create_pca9552(soc, 7, 0x30);
 create_pca9552(soc, 7, 0x31);
@@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), "max31785", 
0x52);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x4a);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
 create_pca9552(soc, 8, 0x60);
 create_pca9552(soc, 8, 0x61);
 /* Bus 8: ucd90320@11 */
@@ -771,11 +762,11 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(&g

[PATCH v5 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-27 Thread Peter Delevoryas
- Create aspeed_eeprom.c and aspeed_eeprom.h
- Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
- Include aspeed_eeprom.h in aspeed.c
- Add fby35_bmc_fruid data
- Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with data
  from aspeed_eeprom.c

wget 
https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
...
user: root
pass: 0penBmc
...
root@bmc-oob:~# fruid-util bb

FRU Information   : Baseboard
---   : --
Chassis Type  : Rack Mount Chassis
Chassis Part Number   : N/A
Chassis Serial Number : N/A
Board Mfg Date: Fri Jan  7 10:30:00 2022
Board Mfg : XX
Board Product : Management Board wBMC
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : N/A
root@bmc-oob:~# fruid-util bmc

FRU Information   : BMC
---   : --
Board Mfg Date: Mon Jan 10 21:42:00 2022
Board Mfg : XX
Board Product : BMC Storage Module
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : Config A
root@bmc-oob:~# fruid-util nic

FRU Information   : NIC
---   : --
Board Mfg Date: Tue Nov  2 08:51:00 2021
Board Mfg : 
Board Product : Mellanox ConnectX-6 DX OCP3.0
Board Serial  : 
Board Part Number : X
Board FRU ID  : FRU Ver 0.02
Product Manufacturer  : 
Product Name  : Mellanox ConnectX-6 DX OCP3.0
Product Part Number   : X
Product Version   : A9
Product Serial: 
Product Custom Data 3 : ConnectX-6 DX

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Joel Stanley 
Reviewed-by: Corey Minyard 
---
 hw/arm/aspeed.c| 10 --
 hw/arm/aspeed_eeprom.c | 82 ++
 hw/arm/aspeed_eeprom.h | 19 ++
 hw/arm/meson.build |  1 +
 4 files changed, 109 insertions(+), 3 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c929c61d582a..624b82c6f62b 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -14,6 +14,7 @@
 #include "hw/arm/boot.h"
 #include "hw/arm/aspeed.h"
 #include "hw/arm/aspeed_soc.h"
+#include "hw/arm/aspeed_eeprom.h"
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
@@ -940,9 +941,12 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
 
 at24c_eeprom_init(i2c[4], 0x51, 128 * KiB);
 at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
-at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
+at24c_eeprom_init_rom(i2c[8], 0x50, 32 * KiB, fby35_nic_fruid,
+  fby35_nic_fruid_len);
+at24c_eeprom_init_rom(i2c[11], 0x51, 128 * KiB, fby35_bb_fruid,
+  fby35_bb_fruid_len);
+at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
+  fby35_bmc_fruid_len);
 
 /*
  * TODO: There is a multi-master i2c connection to an AST1030 MiniBMC on
diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
new file mode 100644
index ..04463acc9d02
--- /dev/null
+++ b/hw/arm/aspeed_eeprom.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include "aspeed_eeprom.h"
+
+const uint8_t fby35_nic_fruid[] = {
+0x01, 0x00, 0x00, 0x01, 0x0f, 0x20, 0x00, 0xcf, 0x01, 0x0e, 0x19, 0xd7,
+0x5e, 0xcf, 0xc8, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0

[PATCH v5 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-27 Thread Peter Delevoryas
This helper is useful in board initialization because lets users initialize and
realize an EEPROM on an I2C bus with a single function call.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Joel Stanley 
Reviewed-by: Corey Minyard 
---
 hw/arm/aspeed.c | 10 +-
 hw/arm/npcm7xx_boards.c | 20 +---
 hw/nvram/eeprom_at24c.c | 12 
 include/hw/nvram/eeprom_at24c.h | 23 +++
 4 files changed, 41 insertions(+), 24 deletions(-)
 create mode 100644 include/hw/nvram/eeprom_at24c.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef729f..1f9799d4321e 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -17,6 +17,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/sensor/tmp105.h"
 #include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
@@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
 arm_load_kernel(ARM_CPU(first_cpu), machine, _board_binfo);
 }
 
-static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe29..9b31207a06e9 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -21,6 +21,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
-  uint32_t rsize)
-{
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
-}
-
 static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
   NPCM7xxState *soc, const int *fan_counts)
 {
@@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
 
 /* TODO: Add remaining i2c devices. */
 }
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 2d4d8b952f38..98857e3626b9 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -12,6 +12,7 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
@@ -128,6 +129,17 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 return 0;
 }
 
+I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
+{
+I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
+DeviceState *dev = DEVICE(i2c_dev);
+
+qdev_prop_set_uint32(dev, "rom-size", rom_size);
+i2c_slave_realize_and_unref(i2

Re: [PATCH v4 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-27 Thread Peter Delevoryas
On Fri, Jan 27, 2023 at 08:42:40AM +0100, Cédric Le Goater wrote:
> > > >   I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > > > rom_size)
> > > >   {
> > > > -I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
> > > > -DeviceState *dev = DEVICE(i2c_dev);
> > > > +return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
> > > > +}
> > > > +
> > > > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > > > rom_size,
> > > > +const uint8_t *init_rom, uint32_t 
> > > > init_rom_size)
> > > > +{
> > > > +EEPROMState *s;
> > > > +
> > > > +s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
> > > > +
> > > > +qdev_prop_set_uint8(DEVICE(s), "address", address);
> > > 
> > > Why did you switch from using i2c_slave_new()?  Using it is more
> > > documentation and future-proofing than convenience.
> > 
> > Oh, yeah that's my bad. I was probably doing it so that all the 
> > qdev_prop_set
> > calls to the object are in the same place, but I probably should have just 
> > kept
> > i2c_slave_new() and initialized only the at24c-eeprom properties here, 
> > instead
> > of initializing the I2CSlave ones too.
> 
> Will you send a v5 ?

Oh! Yeah sure: I thought I had already missed the boat because I thought you
sent a pull request, but I see that it hasn't been pulled yet.

- Peter

> 
> Thanks,
> 
> C.



Re: [PATCH v4 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-25 Thread Peter Delevoryas
On Wed, Jan 25, 2023 at 03:41:30PM -0600, Corey Minyard wrote:
> On Tue, Jan 17, 2023 at 06:42:14PM -0800, Peter Delevoryas wrote:
> > EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
> > I would expect the I2C state machine to be reset to default values, but I
> > wouldn't really expect the memory to change at all.
> 
> Yes, I agree, I was actually wondering about this reviewing earlier
> changes.  Thanks for fixing this.

Oh great! I'm glad everyone has agreed with this so far.

- Peter

> 
> Reviewed-by: Corey Minyard 
> 
> > 
> > The current implementation of the at24c EEPROM resets its internal memory on
> > reset. This matches the specification in docs/devel/reset.rst:
> > 
> >   Cold reset is supported by every resettable object. In QEMU, it means we 
> > reset
> >   to the initial state corresponding to the start of QEMU; this might differ
> >   from what is a real hardware cold reset. It differs from other resets 
> > (like
> >   warm or bus resets) which may keep certain parts untouched.
> > 
> > But differs from my intuition. For example, if someone writes some 
> > information
> > to an EEPROM, then AC power cycles their board, they would expect the 
> > EEPROM to
> > retain that information. It's very useful to be able to test things like 
> > this
> > in QEMU as well, to verify software instrumentation like determining the 
> > cause
> > of a reboot.
> > 
> > Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
> > Signed-off-by: Peter Delevoryas 
> > Reviewed-by: Joel Stanley 
> > ---
> >  hw/nvram/eeprom_at24c.c | 22 ++
> >  1 file changed, 10 insertions(+), 12 deletions(-)
> > 
> > diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> > index f8d751fa278d..5074776bff04 100644
> > --- a/hw/nvram/eeprom_at24c.c
> > +++ b/hw/nvram/eeprom_at24c.c
> > @@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, 
> > Error **errp)
> >  }
> >  
> >  ee->mem = g_malloc0(ee->rsize);
> > -
> > -}
> > -
> > -static
> > -void at24c_eeprom_reset(DeviceState *state)
> > -{
> > -EEPROMState *ee = AT24C_EE(state);
> > -
> > -ee->changed = false;
> > -ee->cur = 0;
> > -ee->haveaddr = 0;
> > -
> >  memset(ee->mem, 0, ee->rsize);
> >  
> >  if (ee->init_rom) {
> > @@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
> >  }
> >  }
> >  
> > +static
> > +void at24c_eeprom_reset(DeviceState *state)
> > +{
> > +EEPROMState *ee = AT24C_EE(state);
> > +
> > +ee->changed = false;
> > +ee->cur = 0;
> > +ee->haveaddr = 0;
> > +}
> > +
> >  static Property at24c_eeprom_props[] = {
> >  DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
> >  DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
> > -- 
> > 2.39.0
> > 
> > 



Re: [PATCH v4 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-25 Thread Peter Delevoryas
On Wed, Jan 25, 2023 at 03:36:23PM -0600, Corey Minyard wrote:
> On Tue, Jan 17, 2023 at 06:42:12PM -0800, Peter Delevoryas wrote:
> > Allows users to specify binary data to initialize an EEPROM, allowing users 
> > to
> > emulate data programmed at manufacturing time.
> > 
> > - Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
> > - Added at24c_eeprom_init_rom helper function to initialize attributes
> > - If -drive property is provided, it overrides init_rom data
> > 
> > Signed-off-by: Peter Delevoryas 
> > Reviewed-by: Joel Stanley 
> > ---
> >  hw/nvram/eeprom_at24c.c | 37 -
> >  include/hw/nvram/eeprom_at24c.h | 16 ++
> >  2 files changed, 48 insertions(+), 5 deletions(-)
> > 
> > diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> > index 98857e3626b9..f8d751fa278d 100644
> > --- a/hw/nvram/eeprom_at24c.c
> > +++ b/hw/nvram/eeprom_at24c.c
> > @@ -50,6 +50,9 @@ struct EEPROMState {
> >  uint8_t *mem;
> >  
> >  BlockBackend *blk;
> > +
> > +const uint8_t *init_rom;
> > +uint32_t init_rom_size;
> >  };
> >  
> >  static
> > @@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
> >  
> >  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size)
> >  {
> > -I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
> > -DeviceState *dev = DEVICE(i2c_dev);
> > +return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
> > +}
> > +
> > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size,
> > +const uint8_t *init_rom, uint32_t 
> > init_rom_size)
> > +{
> > +EEPROMState *s;
> > +
> > +s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
> > +
> > +qdev_prop_set_uint8(DEVICE(s), "address", address);
> 
> Why did you switch from using i2c_slave_new()?  Using it is more
> documentation and future-proofing than convenience.

Oh, yeah that's my bad. I was probably doing it so that all the qdev_prop_set
calls to the object are in the same place, but I probably should have just kept
i2c_slave_new() and initialized only the at24c-eeprom properties here, instead
of initializing the I2CSlave ones too.

- Peter

> 
> Other than that, looks good to me.
> 
> Reviewed-by: Corey Minyard 
> 
> > +qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
> >  
> > -qdev_prop_set_uint32(dev, "rom-size", rom_size);
> > -i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> > +/* TODO: Model init_rom with QOM properties. */
> > +s->init_rom = init_rom;
> > +s->init_rom_size = init_rom_size;
> >  
> > -return i2c_dev;
> > +i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
> > +
> > +return I2C_SLAVE(s);
> >  }
> >  
> >  static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
> >  {
> >  EEPROMState *ee = AT24C_EE(dev);
> >  
> > +if (ee->init_rom_size > ee->rsize) {
> > +error_setg(errp, "%s: init rom is larger than rom: %u > %u",
> > +   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
> > +return;
> > +}
> > +
> >  if (ee->blk) {
> >  int64_t len = blk_getlength(ee->blk);
> >  
> > @@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, 
> > Error **errp)
> >  }
> >  
> >  ee->mem = g_malloc0(ee->rsize);
> > +
> >  }
> >  
> >  static
> > @@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
> >  
> >  memset(ee->mem, 0, ee->rsize);
> >  
> > +if (ee->init_rom) {
> > +memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
> > +}
> > +
> >  if (ee->blk) {
> >  int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
> >  
> > diff --git a/include/hw/nvram/eeprom_at24c.h 
> > b/include/hw/nvram/eeprom_at24c.h
> > index 196db309d451..acb9857b2add 100644
> > --- a/include/hw/nvram/eeprom_at24c.h
> > +++ b/include/hw/nvram/eeprom_at24c.h
> > @@ -20,4 +20,20 @@
> >   */
> >  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size);
> >  
> > +
> > +/*
> > + * Create and realize an AT24C EEPROM device on the heap with initial data.
> > + * @bus: I2C bus to put it on
> > + * @address: I2C address of the EEPROM slave when put on a bus
> > + * @rom_size: size of the EEPROM
> > + * @init_rom: Array of bytes to initialize EEPROM memory with
> > + * @init_rom_size: Size of @init_rom, must be less than or equal to 
> > @rom_size
> > + *
> > + * Create the device state structure, initialize it, put it on the 
> > specified
> > + * @bus, and drop the reference to it (the device is realized). Copies the 
> > data
> > + * from @init_rom to the beginning of the EEPROM memory buffer.
> > + */
> > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size,
> > +const uint8_t *init_rom, uint32_t 
> > init_rom_size);
> > +
> >  #endif
> > -- 
> > 2.39.0
> > 
> > 



Re: [PATCH v4 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-25 Thread Peter Delevoryas
On Wed, Jan 25, 2023 at 04:53:20PM +, Ninad S Palsule wrote:
> Signed-off-by: Peter Delevoryas pe...@pjd.dev<mailto:pe...@pjd.dev>
> Reviewed-by: Joel Stanley j...@jms.id.au<mailto:j...@jms.id.au>
> 
> Tested-by: Ninad Palsule 
> ninadpals...@us.ibm.com<mailto:ninadpals...@us.ibm.com>
> 
> Hi Peter,
> I applied your patches and made sure that different EEPROM images can be 
> loaded from
> appropriate image files and it is working as expected.

Thanks Ninad, this is a good regression test to make sure I didn't break the
existing drive proprerty.

- Peter

> 
> # Used following command to invoke the qemu.
> qemu-system-arm -M rainier-bmc -nographic \
>   -kernel fitImage-linux.bin \
>   -dtb aspeed-bmc-ibm-rainier.dtb \
>   -initrd obmc-phosphor-initramfs.rootfs.cpio.xz \
>   -drive file=obmc-phosphor-image.rootfs.wic.qcow2,if=sd,index=2 \
>   -append "rootwait console=ttyS4,115200n8 root=PARTLABEL=rofs-a" \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.0,address=0x51,drive=a,rom-size=32768 -drive 
> file=tpm.eeprom.bin,format=raw,if=none,id=a \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.7,address=0x50,drive=b,rom-size=65536 -drive 
> file=oppanel.eeprom.bin,format=raw,if=none,id=b \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.7,address=0x51,drive=c,rom-size=65536 -drive 
> file=lcd.eeprom.bin,format=raw,if=none,id=c \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.8,address=0x50,drive=d,rom-size=65536 -drive 
> file=baseboard.eeprom.bin,format=raw,if=none,id=d \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.8,address=0x51,drive=e,rom-size=65536 -drive 
> file=bmc.eeprom.bin,format=raw,if=none,id=e \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.9,address=0x50,drive=f,rom-size=131072 -drive 
> file=vrm.eeprom.bin,format=raw,if=none,id=f \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.10,address=0x50,drive=g,rom-size=131072 
> -drive file=vrm.eeprom.bin,format=raw,if=none,id=g \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.13,address=0x50,drive=h,rom-size=65536 -drive 
> file=nvme.eeprom.bin,format=raw,if=none,id=h \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.14,address=0x50,drive=i,rom-size=65536 -drive 
> file=nvme.eeprom.bin,format=raw,if=none,id=i \
>   -device 
> at24c-eeprom,bus=aspeed.i2c.bus.15,address=0x50,drive=j,rom-size=65536 -drive 
> file=nvme.eeprom.bin,format=raw,if=none,id=j



Re: [PATCH v4 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-18 Thread Peter Delevoryas
On Wed, Jan 18, 2023 at 11:31:57AM +0100, Cédric Le Goater wrote:
> On 1/18/23 03:42, Peter Delevoryas wrote:
> > - Create aspeed_eeprom.c and aspeed_eeprom.h
> > - Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
> > - Include aspeed_eeprom.h in aspeed.c
> > - Add fby35_bmc_fruid data
> > - Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with 
> > data
> >from aspeed_eeprom.c
> > 
> > wget 
> > https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
> > qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
> > ...
> > user: root
> > pass: 0penBmc
> > ...
> > root@bmc-oob:~# fruid-util bb
> > 
> > FRU Information   : Baseboard
> > ---   : --
> > Chassis Type  : Rack Mount Chassis
> > Chassis Part Number   : N/A
> > Chassis Serial Number : N/A
> > Board Mfg Date: Fri Jan  7 10:30:00 2022
> > Board Mfg : XX
> > Board Product : Management Board wBMC
> > Board Serial  : X
> > Board Part Number : XX
> > Board FRU ID  : 1.0
> > Board Custom Data 1   : X
> > Board Custom Data 2   : XX
> > Product Manufacturer  : XX
> > Product Name  : Yosemite V3.5 EVT2
> > Product Part Number   : XX
> > Product Version   : EVT2
> > Product Serial: X
> > Product Asset Tag : XXX
> > Product FRU ID: 1.0
> > Product Custom Data 1 : X
> > Product Custom Data 2 : N/A
> > root@bmc-oob:~# fruid-util bmc
> > 
> > FRU Information   : BMC
> > ---   : --
> > Board Mfg Date: Mon Jan 10 21:42:00 2022
> > Board Mfg : XX
> > Board Product : BMC Storage Module
> > Board Serial  : X
> > Board Part Number : XX
> > Board FRU ID  : 1.0
> > Board Custom Data 1   : X
> > Board Custom Data 2   : XX
> > Product Manufacturer  : XX
> > Product Name  : Yosemite V3.5 EVT2
> > Product Part Number   : XX
> > Product Version   : EVT2
> > Product Serial: X
> > Product Asset Tag : XXX
> > Product FRU ID: 1.0
> > Product Custom Data 1 : X
> > Product Custom Data 2 : Config A
> > root@bmc-oob:~# fruid-util nic
> > 
> > FRU Information   : NIC
> > ---   : --
> > Board Mfg Date: Tue Nov  2 08:51:00 2021
> > Board Mfg : 
> > Board Product : Mellanox ConnectX-6 DX OCP3.0
> > Board Serial  : 
> > Board Part Number : X
> > Board FRU ID  : FRU Ver 0.02
> > Product Manufacturer  : 
> > Product Name  : Mellanox ConnectX-6 DX OCP3.0
> > Product Part Number   : X
> > Product Version   : A9
> > Product Serial: 
> > Product Custom Data 3 : ConnectX-6 DX
> > 
> > Signed-off-by: Peter Delevoryas 
> > Reviewed-by: Cédric Le Goater 
> > Reviewed-by: Joel Stanley 
> > ---
> >   hw/arm/aspeed.c| 10 --
> >   hw/arm/aspeed_eeprom.c | 78 ++
> >   hw/arm/aspeed_eeprom.h | 16 +
> >   hw/arm/meson.build |  1 +
> >   4 files changed, 102 insertions(+), 3 deletions(-)
> >   create mode 100644 hw/arm/aspeed_eeprom.c
> >   create mode 100644 hw/arm/aspeed_eeprom.h
> > 
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > index c929c61d582a..382965f82c38 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -14,6 +14,7 @@
> >   #include "hw/arm/boot.h"
> >   #include "hw/arm/aspeed.h"
> >   #include "hw/arm/aspeed_soc.h"
> > +#include "hw/arm/aspeed_eeprom.h"
> >   #include "hw/i2c/i2c_mux_pca954x.h"
> >   #include "hw/i2c/smbus_eeprom.h"
> >   #include "hw/misc/pca9552.h"
> > @@ -940,9 +941,12 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
> >   at24c_eeprom_init(i2c[4], 0x51, 128 * KiB);
> >   at24c

[PATCH v4 2/5] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-17 Thread Peter Delevoryas
aspeed_eeprom_init is an exact copy of at24c_eeprom_init, not needed.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Joel Stanley 
---
 hw/arm/aspeed.c | 95 ++---
 1 file changed, 43 insertions(+), 52 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1f9799d4321e..c929c61d582a 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
   eeprom_buf);
 }
 
-static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
@@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 AspeedSoCState *soc = >soc;
 I2CSlave *i2c_mux;
 
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
 
 create_pca9552(soc, 3, 0x61);
 
@@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4a);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
 create_pca9552(soc, 4, 0x60);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), TYPE_TMP105,
@@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 create_pca9552(soc, 5, 0x61);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6), TYPE_TMP105,
  0x48);
@@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4b);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
 
 create_pca9552(soc, 7, 0x30);
 create_pca9552(soc, 7, 0x31);
@@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), "max31785", 
0x52);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x4a);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
 create_pca9552(soc, 8, 0x60);
 create_pca9552(soc, 8, 0x61);
 /* Bus 8: ucd90320@11 */
@@ -771,11 +762,11 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423&quo

[PATCH v4 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-17 Thread Peter Delevoryas
This helper is useful in board initialization because lets users initialize and
realize an EEPROM on an I2C bus with a single function call.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Joel Stanley 
---
 hw/arm/aspeed.c | 10 +-
 hw/arm/npcm7xx_boards.c | 20 +---
 hw/nvram/eeprom_at24c.c | 12 
 include/hw/nvram/eeprom_at24c.h | 23 +++
 4 files changed, 41 insertions(+), 24 deletions(-)
 create mode 100644 include/hw/nvram/eeprom_at24c.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef729f..1f9799d4321e 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -17,6 +17,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/sensor/tmp105.h"
 #include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
@@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
 arm_load_kernel(ARM_CPU(first_cpu), machine, _board_binfo);
 }
 
-static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe29..9b31207a06e9 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -21,6 +21,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
-  uint32_t rsize)
-{
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
-}
-
 static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
   NPCM7xxState *soc, const int *fan_counts)
 {
@@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
 
 /* TODO: Add remaining i2c devices. */
 }
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 2d4d8b952f38..98857e3626b9 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -12,6 +12,7 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
@@ -128,6 +129,17 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 return 0;
 }
 
+I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
+{
+I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
+DeviceState *dev = DEVICE(i2c_dev);
+
+qdev_prop_set_uint32(dev, "rom-size", rom_size);
+i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+
+

[PATCH v4 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-17 Thread Peter Delevoryas
Allows users to specify binary data to initialize an EEPROM, allowing users to
emulate data programmed at manufacturing time.

- Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
- Added at24c_eeprom_init_rom helper function to initialize attributes
- If -drive property is provided, it overrides init_rom data

Signed-off-by: Peter Delevoryas 
Reviewed-by: Joel Stanley 
---
 hw/nvram/eeprom_at24c.c | 37 -
 include/hw/nvram/eeprom_at24c.h | 16 ++
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 98857e3626b9..f8d751fa278d 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -50,6 +50,9 @@ struct EEPROMState {
 uint8_t *mem;
 
 BlockBackend *blk;
+
+const uint8_t *init_rom;
+uint32_t init_rom_size;
 };
 
 static
@@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
 {
-I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
-DeviceState *dev = DEVICE(i2c_dev);
+return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
+}
+
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size)
+{
+EEPROMState *s;
+
+s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
+
+qdev_prop_set_uint8(DEVICE(s), "address", address);
+qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
 
-qdev_prop_set_uint32(dev, "rom-size", rom_size);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+/* TODO: Model init_rom with QOM properties. */
+s->init_rom = init_rom;
+s->init_rom_size = init_rom_size;
 
-return i2c_dev;
+i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
+
+return I2C_SLAVE(s);
 }
 
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
 
+if (ee->init_rom_size > ee->rsize) {
+error_setg(errp, "%s: init rom is larger than rom: %u > %u",
+   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
+return;
+}
+
 if (ee->blk) {
 int64_t len = blk_getlength(ee->blk);
 
@@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
+
 }
 
 static
@@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
 
 memset(ee->mem, 0, ee->rsize);
 
+if (ee->init_rom) {
+memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
+}
+
 if (ee->blk) {
 int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
 
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
index 196db309d451..acb9857b2add 100644
--- a/include/hw/nvram/eeprom_at24c.h
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -20,4 +20,20 @@
  */
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
 
+
+/*
+ * Create and realize an AT24C EEPROM device on the heap with initial data.
+ * @bus: I2C bus to put it on
+ * @address: I2C address of the EEPROM slave when put on a bus
+ * @rom_size: size of the EEPROM
+ * @init_rom: Array of bytes to initialize EEPROM memory with
+ * @init_rom_size: Size of @init_rom, must be less than or equal to @rom_size
+ *
+ * Create the device state structure, initialize it, put it on the specified
+ * @bus, and drop the reference to it (the device is realized). Copies the data
+ * from @init_rom to the beginning of the EEPROM memory buffer.
+ */
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size);
+
 #endif
-- 
2.39.0




[PATCH v4 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-17 Thread Peter Delevoryas
EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
I would expect the I2C state machine to be reset to default values, but I
wouldn't really expect the memory to change at all.

The current implementation of the at24c EEPROM resets its internal memory on
reset. This matches the specification in docs/devel/reset.rst:

  Cold reset is supported by every resettable object. In QEMU, it means we reset
  to the initial state corresponding to the start of QEMU; this might differ
  from what is a real hardware cold reset. It differs from other resets (like
  warm or bus resets) which may keep certain parts untouched.

But differs from my intuition. For example, if someone writes some information
to an EEPROM, then AC power cycles their board, they would expect the EEPROM to
retain that information. It's very useful to be able to test things like this
in QEMU as well, to verify software instrumentation like determining the cause
of a reboot.

Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
Signed-off-by: Peter Delevoryas 
Reviewed-by: Joel Stanley 
---
 hw/nvram/eeprom_at24c.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index f8d751fa278d..5074776bff04 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
-
-}
-
-static
-void at24c_eeprom_reset(DeviceState *state)
-{
-EEPROMState *ee = AT24C_EE(state);
-
-ee->changed = false;
-ee->cur = 0;
-ee->haveaddr = 0;
-
 memset(ee->mem, 0, ee->rsize);
 
 if (ee->init_rom) {
@@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
 }
 }
 
+static
+void at24c_eeprom_reset(DeviceState *state)
+{
+EEPROMState *ee = AT24C_EE(state);
+
+ee->changed = false;
+ee->cur = 0;
+ee->haveaddr = 0;
+}
+
 static Property at24c_eeprom_props[] = {
 DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
 DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
-- 
2.39.0




[PATCH v4 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-17 Thread Peter Delevoryas
- Create aspeed_eeprom.c and aspeed_eeprom.h
- Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
- Include aspeed_eeprom.h in aspeed.c
- Add fby35_bmc_fruid data
- Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with data
  from aspeed_eeprom.c

wget 
https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
...
user: root
pass: 0penBmc
...
root@bmc-oob:~# fruid-util bb

FRU Information   : Baseboard
---   : --
Chassis Type  : Rack Mount Chassis
Chassis Part Number   : N/A
Chassis Serial Number : N/A
Board Mfg Date: Fri Jan  7 10:30:00 2022
Board Mfg : XX
Board Product : Management Board wBMC
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : N/A
root@bmc-oob:~# fruid-util bmc

FRU Information   : BMC
---   : --
Board Mfg Date: Mon Jan 10 21:42:00 2022
Board Mfg : XX
Board Product : BMC Storage Module
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : Config A
root@bmc-oob:~# fruid-util nic

FRU Information   : NIC
---   : --
Board Mfg Date: Tue Nov  2 08:51:00 2021
Board Mfg : 
Board Product : Mellanox ConnectX-6 DX OCP3.0
Board Serial  : 
Board Part Number : X
Board FRU ID  : FRU Ver 0.02
Product Manufacturer  : 
Product Name  : Mellanox ConnectX-6 DX OCP3.0
Product Part Number   : X
Product Version   : A9
Product Serial: 
Product Custom Data 3 : ConnectX-6 DX

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Joel Stanley 
---
 hw/arm/aspeed.c| 10 --
 hw/arm/aspeed_eeprom.c | 78 ++
 hw/arm/aspeed_eeprom.h | 16 +
 hw/arm/meson.build |  1 +
 4 files changed, 102 insertions(+), 3 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c929c61d582a..382965f82c38 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -14,6 +14,7 @@
 #include "hw/arm/boot.h"
 #include "hw/arm/aspeed.h"
 #include "hw/arm/aspeed_soc.h"
+#include "hw/arm/aspeed_eeprom.h"
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
@@ -940,9 +941,12 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
 
 at24c_eeprom_init(i2c[4], 0x51, 128 * KiB);
 at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
-at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
+at24c_eeprom_init_rom(i2c[8], 0x50, 32 * KiB, fby35_nic_fruid,
+  sizeof(fby35_nic_fruid));
+at24c_eeprom_init_rom(i2c[11], 0x51, 128 * KiB, fby35_bb_fruid,
+  sizeof(fby35_bb_fruid));
+at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
+  sizeof(fby35_bmc_fruid));
 
 /*
  * TODO: There is a multi-master i2c connection to an AST1030 MiniBMC on
diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
new file mode 100644
index ..9d0700d4b709
--- /dev/null
+++ b/hw/arm/aspeed_eeprom.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include "aspeed_eeprom.h"
+
+const uint8_t fby35_nic_fruid[] = {
+0x01, 0x00, 0x00, 0x01, 0x0f, 0x20, 0x00, 0xcf, 0x01, 0x0e, 0x19, 0xd7,
+0x5e, 0xcf, 0xc8, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xdd,
+0x4d, 0

[PATCH v4 0/5] hw/nvram/eeprom_at24c: Cleanup + FRUID EEPROM init example

2023-01-17 Thread Peter Delevoryas
v1: https://lore.kernel.org/qemu-devel/20230114170151.87833-1-pe...@pjd.dev/
v2:
- Squashed 3 commits from original series into extract helper commit
- Dropped last 2 commits from original series
- Changed at24c_eeprom_init to return the I2CSlave object
- Added commit to introduce at24c-eeprom "init_rom" attribute
- Added aspeed_eeprom.c and fby35-bmc BMC FRUID EEPROM initialization
- Added commit to change reset behavior for at24c-eeprom (optional)
v3:
- Added doc comments to function headers
- Added fby35 NIC and baseboard EEPROM's (to illustrate 2+ EEPROM's)
- Replaced "extern uint32 fby35_bmc_fruid_size" by adding explicit array
  sizes, e.g. "extern uint8_t fby35_bmc_fruid[200]".
- Fixed Meta Platforms licenses by adding SPDX-License-Identifier for GPL2.
- Moved ee->init_rom initialization code before ee->blk, so that -drive
  property overrides init_rom initialization. This gives more flexibility
  (people can override contents of an AT24C EEPROM using a file for
  debugging/prototyping) while still allowing the init_rom data to be
  specified for a board for default behavior.
v4:
- Moved at24c_eeprom_init_rom doc comment to the patch introducing the
  function (moved from patch 4/5 to patch 3/5).
- Added review tags from Joel

Thanks,
Peter

Peter Delevoryas (5):
  hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton
boards
  hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init
  hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom
helper
  hw/arm/aspeed: Add aspeed_eeprom.c
  hw/nvram/eeprom_at24c: Make reset behavior more like hardware

 hw/arm/aspeed.c | 109 ++--
 hw/arm/aspeed_eeprom.c  |  78 +++
 hw/arm/aspeed_eeprom.h  |  16 +
 hw/arm/meson.build  |   1 +
 hw/arm/npcm7xx_boards.c |  20 ++
 hw/nvram/eeprom_at24c.c |  59 +
 include/hw/nvram/eeprom_at24c.h |  39 
 7 files changed, 235 insertions(+), 87 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h
 create mode 100644 include/hw/nvram/eeprom_at24c.h

-- 
2.39.0




Re: [PATCH v3 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-17 Thread Peter Delevoryas
On Wed, Jan 18, 2023 at 02:22:01AM +, Joel Stanley wrote:
> On Tue, 17 Jan 2023 at 23:24, Peter Delevoryas  wrote:
> >
> > Allows users to specify binary data to initialize an EEPROM, allowing users 
> > to
> > emulate data programmed at manufacturing time.
> 
> I like it. Is there somewhere sensible to add a description to the
> code base? Perhaps as a comment to your new function?

Actually yes, I added the comment to the wrong patch in this series. I'll
submit a v4 really quick to correct that, and include the notes you mentioned
(like the fact that we'll only copy up-to rom-size bytes from the init_rom
data).

> 
> >
> > - Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
> > - Added at24c_eeprom_init_rom helper function to initialize attributes
> > - If -drive property is provided, it overrides init_rom data
> >
> > Signed-off-by: Peter Delevoryas 
> 
> Reviewed-by: Joel Stanley 

Thanks for the reviews!

> 
> > ---
> >  hw/nvram/eeprom_at24c.c | 37 -
> >  include/hw/nvram/eeprom_at24c.h |  2 ++
> >  2 files changed, 34 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> > index 98857e3626b9..f8d751fa278d 100644
> > --- a/hw/nvram/eeprom_at24c.c
> > +++ b/hw/nvram/eeprom_at24c.c
> > @@ -50,6 +50,9 @@ struct EEPROMState {
> >  uint8_t *mem;
> >
> >  BlockBackend *blk;
> > +
> > +const uint8_t *init_rom;
> > +uint32_t init_rom_size;
> >  };
> >
> >  static
> > @@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
> >
> >  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size)
> >  {
> > -I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
> > -DeviceState *dev = DEVICE(i2c_dev);
> > +return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
> > +}
> > +
> > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size,
> > +const uint8_t *init_rom, uint32_t 
> > init_rom_size)
> > +{
> > +EEPROMState *s;
> > +
> > +s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
> > +
> > +qdev_prop_set_uint8(DEVICE(s), "address", address);
> > +qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
> >
> > -qdev_prop_set_uint32(dev, "rom-size", rom_size);
> > -i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> > +/* TODO: Model init_rom with QOM properties. */
> > +s->init_rom = init_rom;
> > +s->init_rom_size = init_rom_size;
> >
> > -return i2c_dev;
> > +i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
> > +
> > +return I2C_SLAVE(s);
> >  }
> >
> >  static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
> >  {
> >  EEPROMState *ee = AT24C_EE(dev);
> >
> > +if (ee->init_rom_size > ee->rsize) {
> > +error_setg(errp, "%s: init rom is larger than rom: %u > %u",
> > +   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
> > +return;
> > +}
> > +
> >  if (ee->blk) {
> >  int64_t len = blk_getlength(ee->blk);
> >
> > @@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, 
> > Error **errp)
> >  }
> >
> >  ee->mem = g_malloc0(ee->rsize);
> > +
> >  }
> >
> >  static
> > @@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
> >
> >  memset(ee->mem, 0, ee->rsize);
> >
> > +if (ee->init_rom) {
> > +memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
> 
> I like the MIN here; good usability feature. It's worth documenting too.
> 
> > +}
> > +
> >  if (ee->blk) {
> >  int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
> >
> > diff --git a/include/hw/nvram/eeprom_at24c.h 
> > b/include/hw/nvram/eeprom_at24c.h
> > index 196db309d451..5c9149331144 100644
> > --- a/include/hw/nvram/eeprom_at24c.h
> > +++ b/include/hw/nvram/eeprom_at24c.h
> > @@ -19,5 +19,7 @@
> >   * @bus, and drop the reference to it (the device is realized).
> >   */
> >  I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size);
> > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size,
> > +const uint8_t *init_rom, uint32_t 
> > init_rom_size);
> >
> >  #endif
> > --
> > 2.39.0
> >



[PATCH v3 2/5] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-17 Thread Peter Delevoryas
aspeed_eeprom_init is an exact copy of at24c_eeprom_init, not needed.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/aspeed.c | 95 ++---
 1 file changed, 43 insertions(+), 52 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1f9799d4321e..c929c61d582a 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
   eeprom_buf);
 }
 
-static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
@@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 AspeedSoCState *soc = >soc;
 I2CSlave *i2c_mux;
 
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
 
 create_pca9552(soc, 3, 0x61);
 
@@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4a);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
 create_pca9552(soc, 4, 0x60);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), TYPE_TMP105,
@@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 create_pca9552(soc, 5, 0x61);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6), TYPE_TMP105,
  0x48);
@@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4b);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
 
 create_pca9552(soc, 7, 0x30);
 create_pca9552(soc, 7, 0x31);
@@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), "max31785", 
0x52);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x4a);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
 create_pca9552(soc, 8, 0x60);
 create_pca9552(soc, 8, 0x61);
 /* Bus 8: ucd90320@11 */
@@ -771,11 +762,11 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423", 0x4c);
 i2

[PATCH v3 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-17 Thread Peter Delevoryas
- Create aspeed_eeprom.c and aspeed_eeprom.h
- Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
- Include aspeed_eeprom.h in aspeed.c
- Add fby35_bmc_fruid data
- Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with data
  from aspeed_eeprom.c

wget 
https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
...
user: root
pass: 0penBmc
...
root@bmc-oob:~# fruid-util bb

FRU Information   : Baseboard
---   : --
Chassis Type  : Rack Mount Chassis
Chassis Part Number   : N/A
Chassis Serial Number : N/A
Board Mfg Date: Fri Jan  7 10:30:00 2022
Board Mfg : XX
Board Product : Management Board wBMC
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : N/A
root@bmc-oob:~# fruid-util bmc

FRU Information   : BMC
---   : --
Board Mfg Date: Mon Jan 10 21:42:00 2022
Board Mfg : XX
Board Product : BMC Storage Module
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : Config A
root@bmc-oob:~# fruid-util nic

FRU Information   : NIC
---   : --
Board Mfg Date: Tue Nov  2 08:51:00 2021
Board Mfg : 
Board Product : Mellanox ConnectX-6 DX OCP3.0
Board Serial  : 
Board Part Number : X
Board FRU ID  : FRU Ver 0.02
Product Manufacturer  : 
Product Name  : Mellanox ConnectX-6 DX OCP3.0
Product Part Number   : X
Product Version   : A9
Product Serial: 
Product Custom Data 3 : ConnectX-6 DX

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed.c | 10 +++--
 hw/arm/aspeed_eeprom.c  | 78 +
 hw/arm/aspeed_eeprom.h  | 16 +++
 hw/arm/meson.build  |  1 +
 include/hw/nvram/eeprom_at24c.h | 14 ++
 5 files changed, 116 insertions(+), 3 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c929c61d582a..382965f82c38 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -14,6 +14,7 @@
 #include "hw/arm/boot.h"
 #include "hw/arm/aspeed.h"
 #include "hw/arm/aspeed_soc.h"
+#include "hw/arm/aspeed_eeprom.h"
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
@@ -940,9 +941,12 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
 
 at24c_eeprom_init(i2c[4], 0x51, 128 * KiB);
 at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
-at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
+at24c_eeprom_init_rom(i2c[8], 0x50, 32 * KiB, fby35_nic_fruid,
+  sizeof(fby35_nic_fruid));
+at24c_eeprom_init_rom(i2c[11], 0x51, 128 * KiB, fby35_bb_fruid,
+  sizeof(fby35_bb_fruid));
+at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
+  sizeof(fby35_bmc_fruid));
 
 /*
  * TODO: There is a multi-master i2c connection to an AST1030 MiniBMC on
diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
new file mode 100644
index ..9d0700d4b709
--- /dev/null
+++ b/hw/arm/aspeed_eeprom.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include "aspeed_eeprom.h"
+
+const uint8_t fby35_nic_fruid[] = {
+0x01, 0x00, 0x00, 0x01, 0x0f, 0x20, 0x00, 0xcf, 0x01, 0x0e, 0x19, 0xd7,
+0x5e, 0xcf, 0xc8, 0x58, 0x58, 0x58, 0

[PATCH v3 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-17 Thread Peter Delevoryas
EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
I would expect the I2C state machine to be reset to default values, but I
wouldn't really expect the memory to change at all.

The current implementation of the at24c EEPROM resets its internal memory on
reset. This matches the specification in docs/devel/reset.rst:

  Cold reset is supported by every resettable object. In QEMU, it means we reset
  to the initial state corresponding to the start of QEMU; this might differ
  from what is a real hardware cold reset. It differs from other resets (like
  warm or bus resets) which may keep certain parts untouched.

But differs from my intuition. For example, if someone writes some information
to an EEPROM, then AC power cycles their board, they would expect the EEPROM to
retain that information. It's very useful to be able to test things like this
in QEMU as well, to verify software instrumentation like determining the cause
of a reboot.

Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
Signed-off-by: Peter Delevoryas 
---
 hw/nvram/eeprom_at24c.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index f8d751fa278d..5074776bff04 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
-
-}
-
-static
-void at24c_eeprom_reset(DeviceState *state)
-{
-EEPROMState *ee = AT24C_EE(state);
-
-ee->changed = false;
-ee->cur = 0;
-ee->haveaddr = 0;
-
 memset(ee->mem, 0, ee->rsize);
 
 if (ee->init_rom) {
@@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
 }
 }
 
+static
+void at24c_eeprom_reset(DeviceState *state)
+{
+EEPROMState *ee = AT24C_EE(state);
+
+ee->changed = false;
+ee->cur = 0;
+ee->haveaddr = 0;
+}
+
 static Property at24c_eeprom_props[] = {
 DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
 DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
-- 
2.39.0




[PATCH v3 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-17 Thread Peter Delevoryas
Allows users to specify binary data to initialize an EEPROM, allowing users to
emulate data programmed at manufacturing time.

- Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
- Added at24c_eeprom_init_rom helper function to initialize attributes
- If -drive property is provided, it overrides init_rom data

Signed-off-by: Peter Delevoryas 
---
 hw/nvram/eeprom_at24c.c | 37 -
 include/hw/nvram/eeprom_at24c.h |  2 ++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 98857e3626b9..f8d751fa278d 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -50,6 +50,9 @@ struct EEPROMState {
 uint8_t *mem;
 
 BlockBackend *blk;
+
+const uint8_t *init_rom;
+uint32_t init_rom_size;
 };
 
 static
@@ -131,19 +134,38 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
 {
-I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
-DeviceState *dev = DEVICE(i2c_dev);
+return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
+}
+
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size)
+{
+EEPROMState *s;
+
+s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
+
+qdev_prop_set_uint8(DEVICE(s), "address", address);
+qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
 
-qdev_prop_set_uint32(dev, "rom-size", rom_size);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+/* TODO: Model init_rom with QOM properties. */
+s->init_rom = init_rom;
+s->init_rom_size = init_rom_size;
 
-return i2c_dev;
+i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
+
+return I2C_SLAVE(s);
 }
 
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
 
+if (ee->init_rom_size > ee->rsize) {
+error_setg(errp, "%s: init rom is larger than rom: %u > %u",
+   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
+return;
+}
+
 if (ee->blk) {
 int64_t len = blk_getlength(ee->blk);
 
@@ -163,6 +185,7 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
+
 }
 
 static
@@ -176,6 +199,10 @@ void at24c_eeprom_reset(DeviceState *state)
 
 memset(ee->mem, 0, ee->rsize);
 
+if (ee->init_rom) {
+memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
+}
+
 if (ee->blk) {
 int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
 
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
index 196db309d451..5c9149331144 100644
--- a/include/hw/nvram/eeprom_at24c.h
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -19,5 +19,7 @@
  * @bus, and drop the reference to it (the device is realized).
  */
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size);
 
 #endif
-- 
2.39.0




[PATCH v3 0/5] hw/nvram/eeprom_at24c: Cleanup + FRUID EEPROM init example

2023-01-17 Thread Peter Delevoryas
v1: https://lore.kernel.org/qemu-devel/20230114170151.87833-1-pe...@pjd.dev/
v2:
- Squashed 3 commits from original series into extract helper commit
- Dropped last 2 commits from original series
- Changed at24c_eeprom_init to return the I2CSlave object
- Added commit to introduce at24c-eeprom "init_rom" attribute
- Added aspeed_eeprom.c and fby35-bmc BMC FRUID EEPROM initialization
- Added commit to change reset behavior for at24c-eeprom (optional)
v3:
- Added doc comments to function headers
- Added fby35 NIC and baseboard EEPROM's (to illustrate 2+ EEPROM's)
- Replaced "extern uint32 fby35_bmc_fruid_size" by adding explicit array
  sizes, e.g. "extern uint8_t fby35_bmc_fruid[200]".
- Fixed Meta Platforms licenses by adding SPDX-License-Identifier for GPL2.
- Moved ee->init_rom initialization code before ee->blk, so that -drive
  property overrides init_rom initialization. This gives more flexibility
  (people can override contents of an AT24C EEPROM using a file for
  debugging/prototyping) while still allowing the init_rom data to be
  specified for a board for default behavior.

Thanks,
Peter

Peter Delevoryas (5):
  hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton
boards
  hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init
  hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom
helper
  hw/arm/aspeed: Add aspeed_eeprom.c
  hw/nvram/eeprom_at24c: Make reset behavior more like hardware

 hw/arm/aspeed.c | 109 ++--
 hw/arm/aspeed_eeprom.c  |  78 +++
 hw/arm/aspeed_eeprom.h  |  16 +
 hw/arm/meson.build  |   1 +
 hw/arm/npcm7xx_boards.c |  20 ++
 hw/nvram/eeprom_at24c.c |  59 +
 include/hw/nvram/eeprom_at24c.h |  39 
 7 files changed, 235 insertions(+), 87 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h
 create mode 100644 include/hw/nvram/eeprom_at24c.h

-- 
2.39.0




[PATCH v3 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-17 Thread Peter Delevoryas
This helper is useful in board initialization because lets users initialize and
realize an EEPROM on an I2C bus with a single function call.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed.c | 10 +-
 hw/arm/npcm7xx_boards.c | 20 +---
 hw/nvram/eeprom_at24c.c | 12 
 include/hw/nvram/eeprom_at24c.h | 23 +++
 4 files changed, 41 insertions(+), 24 deletions(-)
 create mode 100644 include/hw/nvram/eeprom_at24c.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef729f..1f9799d4321e 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -17,6 +17,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/sensor/tmp105.h"
 #include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
@@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
 arm_load_kernel(ARM_CPU(first_cpu), machine, _board_binfo);
 }
 
-static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe29..9b31207a06e9 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -21,6 +21,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
-  uint32_t rsize)
-{
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
-}
-
 static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
   NPCM7xxState *soc, const int *fan_counts)
 {
@@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
 
 /* TODO: Add remaining i2c devices. */
 }
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 2d4d8b952f38..98857e3626b9 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -12,6 +12,7 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
@@ -128,6 +129,17 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 return 0;
 }
 
+I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
+{
+I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
+DeviceState *dev = DEVICE(i2c_dev);
+
+qdev_prop_set_uint32(dev, "rom-size", rom_size);
+i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+
+return i2c

Re: [PATCH v2 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-17 Thread Peter Delevoryas
On Tue, Jan 17, 2023 at 10:32:15AM -0800, Peter Delevoryas wrote:
> On Tue, Jan 17, 2023 at 09:00:34AM +0100, Philippe Mathieu-Daudé wrote:
> > On 17/1/23 00:56, Peter Delevoryas wrote:
> > > This helper is useful in board initialization because lets users 
> > > initialize and
> > > realize an EEPROM on an I2C bus with a single function call.
> > > 
> > > Signed-off-by: Peter Delevoryas 
> > > ---
> > >   hw/arm/aspeed.c | 10 +-
> > >   hw/arm/npcm7xx_boards.c | 20 +---
> > >   hw/nvram/eeprom_at24c.c | 12 
> > >   include/hw/nvram/eeprom_at24c.h | 10 ++
> > >   4 files changed, 28 insertions(+), 24 deletions(-)
> > >   create mode 100644 include/hw/nvram/eeprom_at24c.h
> > 
> > > diff --git a/include/hw/nvram/eeprom_at24c.h 
> > > b/include/hw/nvram/eeprom_at24c.h
> > > new file mode 100644
> > > index ..79a36b53ca87
> > > --- /dev/null
> > > +++ b/include/hw/nvram/eeprom_at24c.h
> > > @@ -0,0 +1,10 @@
> > > +/* Copyright (c) Meta Platforms, Inc. and affiliates. */
> > 
> > What license for this copyright?
> 
> Erg, yeah, thanks for calling this out, I did this wrong. Meta has some new
> licensing guidelines and I misinterpreted them. Contributors are just supposed
> to use whatever license the open-source project has, so I'll just change this
> to say it's under GPL2, like the one I used in hw/arm/fby35.c
> 
> > 
> > > +#ifndef EEPROM_AT24C_H
> > > +#define EEPROM_AT24C_H
> > > +
> > > +#include "hw/i2c/i2c.h"
> > 
> >  /**
> >   * Create and realize an AT24C EEPROM device on the heap.
> >   * @bus: I2C bus to put it on
> >   * @addr: I2C address of the EEPROM slave when put on a bus
> >   * @rom_size: size of the EEPROM
> >   *
> >   * Create the device state structure, initialize it, put it on
> >   * the specified @bus, and drop the reference to it (the device
> >   * is realized).
> >   */
> >  I2CSlave *at24c_eeprom_create_simple(I2CBus *bus, uint8_t addr,
> >   size_t rom_size);
> 
> +1, I'll include this comment

Oh, to clarify though: I'm not going to include the rename to the function,
maybe we could do that separately? I kinda want to avoid touching all the
at24c_eeprom_init calls unless I really need to. I know it's just a simple sed,
but also, smbus_eeprom_init is using the "init" suffix, so I'm not sure it's
consistent, although "create_simple" probably _is_ more consistent with devices
in general in QEMU. But anyways, main point, I just want to avoid making any
unnecessary refactoring here, and renaming it completely seems unnecessary.

> 
> > 
> > > +I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > > rom_size);
> > > +
> > > +#endif
> > 
> 



Re: [PATCH v2 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-17 Thread Peter Delevoryas
On Tue, Jan 17, 2023 at 09:08:57AM +0100, Philippe Mathieu-Daudé wrote:
> On 17/1/23 08:39, Cédric Le Goater wrote:
> > On 1/17/23 00:56, Peter Delevoryas wrote:
> > > - Create aspeed_eeprom.c and aspeed_eeprom.h
> > > - Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
> > > - Include aspeed_eeprom.h in aspeed.c
> > > - Add fby35_bmc_fruid data
> > > - Use new at24c_eeprom_init_rom helper to initialize BMC FRUID
> > > EEPROM with data
> > >    from aspeed_eeprom.c
> [...]
> 
> > > diff --git a/hw/arm/aspeed_eeprom.h b/hw/arm/aspeed_eeprom.h
> > > new file mode 100644
> > > index ..89860e37d007
> > > --- /dev/null
> > > +++ b/hw/arm/aspeed_eeprom.h
> > > @@ -0,0 +1,11 @@
> > > +/* Copyright (c) Meta Platforms, Inc. and affiliates. */
> 
> Missing license.

+1, will fix

> 
> > > +#ifndef ASPEED_EEPROM_H
> > > +#define ASPEED_EEPROM_H
> > > +
> > > +#include "qemu/osdep.h"
> > > +
> > > +extern const uint8_t fby35_bmc_fruid[];
> > 
> > 
> > may be define the array with an explicit size to avoid the size variable ?
> > I don't see any good solution.
>  /* Return rom_size and set rombufptr, or return 0 */
>  size_t aspeed_get_default_rom_content(const char *machine_typename,
>const void **rombufptr);
> 
> ?


Hmmm I don't think this would work, cause actually there are more FRUID
EEPROM's than just this one. I only added this one in this commit, but there's
also FRUID EEPROM's from the network card and baseboard. I'll include those 2
EEPROM's in the next version to illustrate.



Re: [PATCH v2 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-17 Thread Peter Delevoryas
On Tue, Jan 17, 2023 at 09:00:34AM +0100, Philippe Mathieu-Daudé wrote:
> On 17/1/23 00:56, Peter Delevoryas wrote:
> > This helper is useful in board initialization because lets users initialize 
> > and
> > realize an EEPROM on an I2C bus with a single function call.
> > 
> > Signed-off-by: Peter Delevoryas 
> > ---
> >   hw/arm/aspeed.c | 10 +-
> >   hw/arm/npcm7xx_boards.c | 20 +---
> >   hw/nvram/eeprom_at24c.c | 12 
> >   include/hw/nvram/eeprom_at24c.h | 10 ++
> >   4 files changed, 28 insertions(+), 24 deletions(-)
> >   create mode 100644 include/hw/nvram/eeprom_at24c.h
> 
> > diff --git a/include/hw/nvram/eeprom_at24c.h 
> > b/include/hw/nvram/eeprom_at24c.h
> > new file mode 100644
> > index ..79a36b53ca87
> > --- /dev/null
> > +++ b/include/hw/nvram/eeprom_at24c.h
> > @@ -0,0 +1,10 @@
> > +/* Copyright (c) Meta Platforms, Inc. and affiliates. */
> 
> What license for this copyright?

Erg, yeah, thanks for calling this out, I did this wrong. Meta has some new
licensing guidelines and I misinterpreted them. Contributors are just supposed
to use whatever license the open-source project has, so I'll just change this
to say it's under GPL2, like the one I used in hw/arm/fby35.c

> 
> > +#ifndef EEPROM_AT24C_H
> > +#define EEPROM_AT24C_H
> > +
> > +#include "hw/i2c/i2c.h"
> 
>  /**
>   * Create and realize an AT24C EEPROM device on the heap.
>   * @bus: I2C bus to put it on
>   * @addr: I2C address of the EEPROM slave when put on a bus
>   * @rom_size: size of the EEPROM
>   *
>   * Create the device state structure, initialize it, put it on
>   * the specified @bus, and drop the reference to it (the device
>   * is realized).
>   */
>  I2CSlave *at24c_eeprom_create_simple(I2CBus *bus, uint8_t addr,
>   size_t rom_size);

+1, I'll include this comment

> 
> > +I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size);
> > +
> > +#endif
> 



Re: [PATCH v2 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-17 Thread Peter Delevoryas
On Tue, Jan 17, 2023 at 08:42:46AM +0100, Cédric Le Goater wrote:
> On 1/17/23 00:56, Peter Delevoryas wrote:
> > EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
> > I would expect the I2C state machine to be reset to default values, but I
> > wouldn't really expect the memory to change at all.
> 
> 
> > 
> > The current implementation of the at24c EEPROM resets its internal memory on
> > reset. This matches the specification in docs/devel/reset.rst:
> > 
> >Cold reset is supported by every resettable object. In QEMU, it means we 
> > reset
> >to the initial state corresponding to the start of QEMU; this might 
> > differ
> >from what is a real hardware cold reset. It differs from other resets 
> > (like
> >warm or bus resets) which may keep certain parts untouched.
> > 
> > But differs from my intuition. For example, if someone writes some 
> > information
> > to an EEPROM, then AC power cycles their board, they would expect the 
> > EEPROM to
> > retain that information. It's very useful to be able to test things like 
> > this
> > in QEMU as well, to verify software instrumentation like determining the 
> > cause
> > of a reboot.
> 
> Yes. should we take into account the "writable" property  ? It is not set to
> false in any model but it could.

We're already using "writable" in at24c_eeprom_send to control writes, do we
need to use it anywhere else? I would assume we shouldn't use it in init/reset,
but maybe you have something specific in mind.

> 
> Thanks,
> 
> C.
> 
> > Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
> > Signed-off-by: Peter Delevoryas 
> > ---
> >   hw/nvram/eeprom_at24c.c | 22 ++
> >   1 file changed, 10 insertions(+), 12 deletions(-)
> > 
> > diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> > index bb9ee75864fe..6bcded7b496c 100644
> > --- a/hw/nvram/eeprom_at24c.c
> > +++ b/hw/nvram/eeprom_at24c.c
> > @@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, 
> > Error **errp)
> >   }
> >   ee->mem = g_malloc0(ee->rsize);
> > -
> > -}
> > -
> > -static
> > -void at24c_eeprom_reset(DeviceState *state)
> > -{
> > -EEPROMState *ee = AT24C_EE(state);
> > -
> > -ee->changed = false;
> > -ee->cur = 0;
> > -ee->haveaddr = 0;
> > -
> >   memset(ee->mem, 0, ee->rsize);
> >   if (ee->blk) {
> > @@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
> >   }
> >   }
> > +static
> > +void at24c_eeprom_reset(DeviceState *state)
> > +{
> > +EEPROMState *ee = AT24C_EE(state);
> > +
> > +ee->changed = false;
> > +ee->cur = 0;
> > +ee->haveaddr = 0;
> > +}
> > +
> >   static Property at24c_eeprom_props[] = {
> >   DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
> >   DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
> 



Re: [PATCH v2 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-17 Thread Peter Delevoryas
On Tue, Jan 17, 2023 at 08:39:06AM +0100, Cédric Le Goater wrote:
> On 1/17/23 00:56, Peter Delevoryas wrote:
> > - Create aspeed_eeprom.c and aspeed_eeprom.h
> > - Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
> > - Include aspeed_eeprom.h in aspeed.c
> > - Add fby35_bmc_fruid data
> > - Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with 
> > data
> >from aspeed_eeprom.c
> > 
> > wget 
> > https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
> > qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
> > ...
> > user: root
> > pass: 0penBmc
> > ...
> > root@bmc-oob:~# fruid-util bmc
> > 
> > FRU Information   : BMC
> > ---   : --
> > Board Mfg Date: Mon Jan 10 21:42:00 2022
> > Board Mfg : XX
> > Board Product : BMC Storage Module
> > Board Serial  : X
> > Board Part Number : XX
> > Board FRU ID  : 1.0
> > Board Custom Data 1   : X
> > Board Custom Data 2   : XX
> > Product Manufacturer  : XX
> > Product Name  : Yosemite V3.5 EVT2
> > Product Part Number   : XX
> > Product Version   : EVT2
> > Product Serial: XXXXX
> > Product Asset Tag : XXX
> > Product FRU ID: 1.0
> > Product Custom Data 1 : X
> > Product Custom Data 2 : Config A
> > 
> > Signed-off-by: Peter Delevoryas 
> 
> Reviewed-by: Cédric Le Goater 
> 
> One little comment below,
> 
> > ---
> >   hw/arm/aspeed.c|  4 +++-
> >   hw/arm/aspeed_eeprom.c | 51 ++
> >   hw/arm/aspeed_eeprom.h | 11 +
> >   hw/arm/meson.build |  1 +
> >   4 files changed, 66 insertions(+), 1 deletion(-)
> >   create mode 100644 hw/arm/aspeed_eeprom.c
> >   create mode 100644 hw/arm/aspeed_eeprom.h
> > 
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > index c929c61d582a..11e423db4538 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -14,6 +14,7 @@
> >   #include "hw/arm/boot.h"
> >   #include "hw/arm/aspeed.h"
> >   #include "hw/arm/aspeed_soc.h"
> > +#include "hw/arm/aspeed_eeprom.h"
> >   #include "hw/i2c/i2c_mux_pca954x.h"
> >   #include "hw/i2c/smbus_eeprom.h"
> >   #include "hw/misc/pca9552.h"
> > @@ -942,7 +943,8 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
> >   at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
> >   at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
> >   at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
> > -at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
> > +at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
> > +  fby35_bmc_fruid_size);
> >   /*
> >* TODO: There is a multi-master i2c connection to an AST1030 MiniBMC 
> > on
> > diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
> > new file mode 100644
> > index ..a5ffa959927b
> > --- /dev/null
> > +++ b/hw/arm/aspeed_eeprom.c
> > @@ -0,0 +1,51 @@
> > +/* Copyright (c) Meta Platforms, Inc. and affiliates. */
> > +
> > +#include "aspeed_eeprom.h"
> > +
> > +const uint8_t fby35_bmc_fruid[] = {
> > +0x01, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0xf1, 0x01, 0x0c, 0x00, 0x36,
> > +0xe6, 0xd0, 0xc6, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2, 0x42, 0x4d,
> > +0x43, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x4d, 0x6f,
> > +0x64, 0x75, 0x6c, 0x65, 0xcd, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xce, 0x58, 0x58, 0x58, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc3, 0x31, 0x2e,
> > +0x30, 0xc9, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc1, 0x39, 0x01, 0x0c, 0x00, 0xc6,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2, 0x59, 0x6f, 0x73, 0x65, 0x6d,
> > +0x69, 0x74, 0x65, 0x20, 0x56, 0x33, 0x2e, 0x35, 0x20, 0x45, 0x56, 0x54,
> > +0x32, 0xce, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0xc4, 0x45, 0x56, 0x54, 0x32, 0xcd, 0x58, 0x58,
> 

Re: [PATCH v2 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-17 Thread Peter Delevoryas
On Tue, Jan 17, 2023 at 08:35:44AM +0100, Cédric Le Goater wrote:
> On 1/17/23 00:56, Peter Delevoryas wrote:
> > Allows users to specify binary data to initialize an EEPROM, allowing users 
> > to
> > emulate data programmed at manufacturing time.
> > 
> > - Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
> > - Added at24c_eeprom_init_rom helper function to initialize attributes
> > 
> > Signed-off-by: Peter Delevoryas 
> > ---
> >   hw/nvram/eeprom_at24c.c | 37 -
> >   include/hw/nvram/eeprom_at24c.h |  2 ++
> >   2 files changed, 34 insertions(+), 5 deletions(-)
> > 
> > diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
> > index 98857e3626b9..bb9ee75864fe 100644
> > --- a/hw/nvram/eeprom_at24c.c
> > +++ b/hw/nvram/eeprom_at24c.c
> > @@ -50,6 +50,9 @@ struct EEPROMState {
> >   uint8_t *mem;
> >   BlockBackend *blk;
> > +
> > +const uint8_t *init_rom;
> > +uint32_t init_rom_size;
> >   };
> >   static
> > @@ -131,13 +134,26 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
> >   I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size)
> >   {
> > -I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
> > -DeviceState *dev = DEVICE(i2c_dev);
> > +return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
> > +}
> > +
> > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size,
> > +const uint8_t *init_rom, uint32_t 
> > init_rom_size)
> > +{
> > +EEPROMState *s;
> > +
> > +s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
> > +
> > +qdev_prop_set_uint8(DEVICE(s), "address", address);
> > +qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
> > -qdev_prop_set_uint32(dev, "rom-size", rom_size);
> > -i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> > +/* TODO: Model init_rom with QOM properties. */
> 
> ok. This can be fixed with a property later when we have support.
> 
> > +s->init_rom = init_rom;
> > +s->init_rom_size = init_rom_size;
> > -return i2c_dev;
> > +i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
> > +
> > +return I2C_SLAVE(s);
> >   }
> >   static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
> > @@ -162,7 +178,14 @@ static void at24c_eeprom_realize(DeviceState *dev, 
> > Error **errp)
> >   }
> >   }
> > +if (ee->init_rom_size > ee->rsize) {
> > +error_setg(errp, "%s: init rom is larger than rom: %u > %u",
> > +   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
> > +return;
> > +}
> > +
> >   ee->mem = g_malloc0(ee->rsize);
> > +
> >   }
> >   static
> > @@ -185,6 +208,10 @@ void at24c_eeprom_reset(DeviceState *state)
> >   }
> >   DPRINTK("Reset read backing file\n");
> >   }
> > +
> > +if (ee->init_rom) {
> > +memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
> > +}
> 
> I don't think we can have both an init_rom and a drive. The realize
> handler should report an error in that case.

+1, I'll include that in v3.

> 
> >   }
> >   static Property at24c_eeprom_props[] = {
> > diff --git a/include/hw/nvram/eeprom_at24c.h 
> > b/include/hw/nvram/eeprom_at24c.h
> > index 79a36b53ca87..e490826ab1d0 100644
> > --- a/include/hw/nvram/eeprom_at24c.h
> > +++ b/include/hw/nvram/eeprom_at24c.h
> > @@ -6,5 +6,7 @@
> >   #include "hw/i2c/i2c.h"
> >   I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size);
> > +I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
> > rom_size,
> > +const uint8_t *init_rom, uint32_t 
> > init_rom_size);
> >   #endif
> 



Re: [PATCH 6/6] hw/arm/aspeed: Init fby35 BMC FRUID EEPROM

2023-01-17 Thread Peter Delevoryas
On Tue, Jan 17, 2023 at 07:47:06AM +0100, Philippe Mathieu-Daudé wrote:
> On 16/1/23 18:23, Peter Delevoryas wrote:
> > On Mon, Jan 16, 2023 at 01:30:19PM +0100, Philippe Mathieu-Daudé wrote:
> > > On 14/1/23 18:01, Peter Delevoryas wrote:
> > > > Signed-off-by: Peter Delevoryas 
> > > > ---
> > > >hw/arm/aspeed.c | 49 
> > > > +
> > > >1 file changed, 49 insertions(+)
> > > > 
> > > > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > > > index c929c61d582a..4ac8ff11a835 100644
> > > > --- a/hw/arm/aspeed.c
> > > > +++ b/hw/arm/aspeed.c
> > > > @@ -922,6 +922,52 @@ static void 
> > > > bletchley_bmc_i2c_init(AspeedMachineState *bmc)
> > > >i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67);
> > > >}
> > > > +static const uint8_t fby35_bmc_fruid[] = {
> > > [...]
> > > 
> > > > +};
> > > > +
> > > >static void fby35_i2c_init(AspeedMachineState *bmc)
> > > >{
> > > >AspeedSoCState *soc = >soc;
> > > > @@ -1363,6 +1409,9 @@ static void fby35_reset(MachineState *state, 
> > > > ShutdownCause reason)
> > > >object_property_set_bool(OBJECT(gpio), "gpioB3", false, 
> > > > _fatal);
> > > >object_property_set_bool(OBJECT(gpio), "gpioB4", false, 
> > > > _fatal);
> > > >object_property_set_bool(OBJECT(gpio), "gpioB5", false, 
> > > > _fatal);
> > > > +
> > > > +at24c_eeprom_write(aspeed_i2c_get_bus(>soc.i2c, 11),
> > > > +   0x54, 0, fby35_bmc_fruid, 
> > > > sizeof(fby35_bmc_fruid));
> > > 
> > > Why transfer the prom content on the i2c bus at each reset?
> > > 
> > > In particular this looks wrong if the prom is initialized with a 'drive'
> > > block backend (using -global).
> > 
> > Yeah, it looks like this might not be the right way to model it. I'm going
> > to try Cedric's suggestions.
> 
> OK, but watch out this is a PROM, not a ROM, meaning it is legitimate
> for a guest to reprogram it, and expect the reprogrammed content after
> reset.

+1

> 
> Shouldn't we put the 'fill default content if no -drive provided' option
> in the device's realize() handler, to avoid overwriting content possibly
> updated by guest before reset?

+1, yeah I think you're right, if somebody is providing a -drive option, we
should allow that to override everything else (default zero initialization,
init ROM initialization, etc).

Because, if they're providing a -drive, they shouldn't need to provide an
initial value, they can just initialize the file with the data they want.



[PATCH v2 2/5] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-16 Thread Peter Delevoryas
aspeed_eeprom_init is an exact copy of at24c_eeprom_init, not needed.

Signed-off-by: Peter Delevoryas 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/aspeed.c | 95 ++---
 1 file changed, 43 insertions(+), 52 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1f9799d4321e..c929c61d582a 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
   eeprom_buf);
 }
 
-static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
@@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 AspeedSoCState *soc = >soc;
 I2CSlave *i2c_mux;
 
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
 
 create_pca9552(soc, 3, 0x61);
 
@@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4a);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
 create_pca9552(soc, 4, 0x60);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), TYPE_TMP105,
@@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 create_pca9552(soc, 5, 0x61);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6), TYPE_TMP105,
  0x48);
@@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4b);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
 
 create_pca9552(soc, 7, 0x30);
 create_pca9552(soc, 7, 0x31);
@@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), "max31785", 
0x52);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x4a);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
 create_pca9552(soc, 8, 0x60);
 create_pca9552(soc, 8, 0x61);
 /* Bus 8: ucd90320@11 */
@@ -771,11 +762,11 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423", 0x4c);
 i2

[PATCH v2 4/5] hw/arm/aspeed: Add aspeed_eeprom.c

2023-01-16 Thread Peter Delevoryas
- Create aspeed_eeprom.c and aspeed_eeprom.h
- Include aspeed_eeprom.c in CONFIG_ASPEED meson source files
- Include aspeed_eeprom.h in aspeed.c
- Add fby35_bmc_fruid data
- Use new at24c_eeprom_init_rom helper to initialize BMC FRUID EEPROM with data
  from aspeed_eeprom.c

wget 
https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock fby35.mtd
...
user: root
pass: 0penBmc
...
root@bmc-oob:~# fruid-util bmc

FRU Information   : BMC
---   : --
Board Mfg Date: Mon Jan 10 21:42:00 2022
Board Mfg : XX
Board Product : BMC Storage Module
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : Config A

Signed-off-by: Peter Delevoryas 
---
 hw/arm/aspeed.c|  4 +++-
 hw/arm/aspeed_eeprom.c | 51 ++
 hw/arm/aspeed_eeprom.h | 11 +
 hw/arm/meson.build |  1 +
 4 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c929c61d582a..11e423db4538 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -14,6 +14,7 @@
 #include "hw/arm/boot.h"
 #include "hw/arm/aspeed.h"
 #include "hw/arm/aspeed_soc.h"
+#include "hw/arm/aspeed_eeprom.h"
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
@@ -942,7 +943,8 @@ static void fby35_i2c_init(AspeedMachineState *bmc)
 at24c_eeprom_init(i2c[6], 0x51, 128 * KiB);
 at24c_eeprom_init(i2c[8], 0x50, 32 * KiB);
 at24c_eeprom_init(i2c[11], 0x51, 128 * KiB);
-at24c_eeprom_init(i2c[11], 0x54, 128 * KiB);
+at24c_eeprom_init_rom(i2c[11], 0x54, 128 * KiB, fby35_bmc_fruid,
+  fby35_bmc_fruid_size);
 
 /*
  * TODO: There is a multi-master i2c connection to an AST1030 MiniBMC on
diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
new file mode 100644
index ..a5ffa959927b
--- /dev/null
+++ b/hw/arm/aspeed_eeprom.c
@@ -0,0 +1,51 @@
+/* Copyright (c) Meta Platforms, Inc. and affiliates. */
+
+#include "aspeed_eeprom.h"
+
+const uint8_t fby35_bmc_fruid[] = {
+0x01, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0xf1, 0x01, 0x0c, 0x00, 0x36,
+0xe6, 0xd0, 0xc6, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2, 0x42, 0x4d,
+0x43, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x4d, 0x6f,
+0x64, 0x75, 0x6c, 0x65, 0xcd, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xce, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc3, 0x31, 0x2e,
+0x30, 0xc9, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc1, 0x39, 0x01, 0x0c, 0x00, 0xc6,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2, 0x59, 0x6f, 0x73, 0x65, 0x6d,
+0x69, 0x74, 0x65, 0x20, 0x56, 0x33, 0x2e, 0x35, 0x20, 0x45, 0x56, 0x54,
+0x32, 0xce, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0xc4, 0x45, 0x56, 0x54, 0x32, 0xcd, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc7,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc3, 0x31, 0x2e, 0x30, 0xc9,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc8, 0x43, 0x6f,
+0x6e, 0x66, 0x69, 0x67, 0x20, 0x41, 0xc1, 0x45, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0

[PATCH v2 1/5] hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton boards

2023-01-16 Thread Peter Delevoryas
This helper is useful in board initialization because lets users initialize and
realize an EEPROM on an I2C bus with a single function call.

Signed-off-by: Peter Delevoryas 
---
 hw/arm/aspeed.c | 10 +-
 hw/arm/npcm7xx_boards.c | 20 +---
 hw/nvram/eeprom_at24c.c | 12 
 include/hw/nvram/eeprom_at24c.h | 10 ++
 4 files changed, 28 insertions(+), 24 deletions(-)
 create mode 100644 include/hw/nvram/eeprom_at24c.h

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef729f..1f9799d4321e 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -17,6 +17,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/sensor/tmp105.h"
 #include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
@@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
 arm_load_kernel(ARM_CPU(first_cpu), machine, _board_binfo);
 }
 
-static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe29..9b31207a06e9 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -21,6 +21,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
-  uint32_t rsize)
-{
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
-}
-
 static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
   NPCM7xxState *soc, const int *fan_counts)
 {
@@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
 
 /* TODO: Add remaining i2c devices. */
 }
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 2d4d8b952f38..98857e3626b9 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -12,6 +12,7 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
@@ -128,6 +129,17 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 return 0;
 }
 
+I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
+{
+I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
+DeviceState *dev = DEVICE(i2c_dev);
+
+qdev_prop_set_uint32(dev, "rom-size", rom_size);
+i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+
+return i2c_dev;
+}
+
 static void at24c_eeprom_realize(DeviceState 

[PATCH v2 5/5] hw/nvram/eeprom_at24c: Make reset behavior more like hardware

2023-01-16 Thread Peter Delevoryas
EEPROM's are a form of non-volatile memory. After power-cycling an EEPROM,
I would expect the I2C state machine to be reset to default values, but I
wouldn't really expect the memory to change at all.

The current implementation of the at24c EEPROM resets its internal memory on
reset. This matches the specification in docs/devel/reset.rst:

  Cold reset is supported by every resettable object. In QEMU, it means we reset
  to the initial state corresponding to the start of QEMU; this might differ
  from what is a real hardware cold reset. It differs from other resets (like
  warm or bus resets) which may keep certain parts untouched.

But differs from my intuition. For example, if someone writes some information
to an EEPROM, then AC power cycles their board, they would expect the EEPROM to
retain that information. It's very useful to be able to test things like this
in QEMU as well, to verify software instrumentation like determining the cause
of a reboot.

Fixes: 5d8424dbd3e8 ("nvram: add AT24Cx i2c eeprom")
Signed-off-by: Peter Delevoryas 
---
 hw/nvram/eeprom_at24c.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index bb9ee75864fe..6bcded7b496c 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -185,18 +185,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 
 ee->mem = g_malloc0(ee->rsize);
-
-}
-
-static
-void at24c_eeprom_reset(DeviceState *state)
-{
-EEPROMState *ee = AT24C_EE(state);
-
-ee->changed = false;
-ee->cur = 0;
-ee->haveaddr = 0;
-
 memset(ee->mem, 0, ee->rsize);
 
 if (ee->blk) {
@@ -214,6 +202,16 @@ void at24c_eeprom_reset(DeviceState *state)
 }
 }
 
+static
+void at24c_eeprom_reset(DeviceState *state)
+{
+EEPROMState *ee = AT24C_EE(state);
+
+ee->changed = false;
+ee->cur = 0;
+ee->haveaddr = 0;
+}
+
 static Property at24c_eeprom_props[] = {
 DEFINE_PROP_UINT32("rom-size", EEPROMState, rsize, 0),
 DEFINE_PROP_BOOL("writable", EEPROMState, writable, true),
-- 
2.39.0




[PATCH v2 3/5] hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom helper

2023-01-16 Thread Peter Delevoryas
Allows users to specify binary data to initialize an EEPROM, allowing users to
emulate data programmed at manufacturing time.

- Added init_rom and init_rom_size attributes to TYPE_AT24C_EE
- Added at24c_eeprom_init_rom helper function to initialize attributes

Signed-off-by: Peter Delevoryas 
---
 hw/nvram/eeprom_at24c.c | 37 -
 include/hw/nvram/eeprom_at24c.h |  2 ++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 98857e3626b9..bb9ee75864fe 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -50,6 +50,9 @@ struct EEPROMState {
 uint8_t *mem;
 
 BlockBackend *blk;
+
+const uint8_t *init_rom;
+uint32_t init_rom_size;
 };
 
 static
@@ -131,13 +134,26 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
 {
-I2CSlave *i2c_dev = i2c_slave_new(TYPE_AT24C_EE, address);
-DeviceState *dev = DEVICE(i2c_dev);
+return at24c_eeprom_init_rom(bus, address, rom_size, NULL, 0);
+}
+
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size)
+{
+EEPROMState *s;
+
+s = AT24C_EE(qdev_new(TYPE_AT24C_EE));
+
+qdev_prop_set_uint8(DEVICE(s), "address", address);
+qdev_prop_set_uint32(DEVICE(s), "rom-size", rom_size);
 
-qdev_prop_set_uint32(dev, "rom-size", rom_size);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+/* TODO: Model init_rom with QOM properties. */
+s->init_rom = init_rom;
+s->init_rom_size = init_rom_size;
 
-return i2c_dev;
+i2c_slave_realize_and_unref(I2C_SLAVE(s), bus, _abort);
+
+return I2C_SLAVE(s);
 }
 
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
@@ -162,7 +178,14 @@ static void at24c_eeprom_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (ee->init_rom_size > ee->rsize) {
+error_setg(errp, "%s: init rom is larger than rom: %u > %u",
+   TYPE_AT24C_EE, ee->init_rom_size, ee->rsize);
+return;
+}
+
 ee->mem = g_malloc0(ee->rsize);
+
 }
 
 static
@@ -185,6 +208,10 @@ void at24c_eeprom_reset(DeviceState *state)
 }
 DPRINTK("Reset read backing file\n");
 }
+
+if (ee->init_rom) {
+memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
+}
 }
 
 static Property at24c_eeprom_props[] = {
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
index 79a36b53ca87..e490826ab1d0 100644
--- a/include/hw/nvram/eeprom_at24c.h
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -6,5 +6,7 @@
 #include "hw/i2c/i2c.h"
 
 I2CSlave *at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
+I2CSlave *at24c_eeprom_init_rom(I2CBus *bus, uint8_t address, uint32_t 
rom_size,
+const uint8_t *init_rom, uint32_t 
init_rom_size);
 
 #endif
-- 
2.39.0




[PATCH v2 0/5] hw/nvram/eeprom_at24c: Cleanup + FRUID EEPROM init example

2023-01-16 Thread Peter Delevoryas
v1: https://lore.kernel.org/qemu-devel/20230114170151.87833-1-pe...@pjd.dev/
v2:
- Squashed 3 commits from original series into extract helper commit
- Dropped last 2 commits from original series
- Changed at24c_eeprom_init to return the I2CSlave object
- Added commit to introduce at24c-eeprom "init_rom" attribute
- Added aspeed_eeprom.c and fby35-bmc BMC FRUID EEPROM initialization
- Added commit to change reset behavior for at24c-eeprom (optional)

The reset behavior one might be controversial, I put it last, you can drop it
if you like.

Thanks,
Peter

Peter Delevoryas (5):
  hw/arm: Extract at24c_eeprom_init helper from Aspeed and Nuvoton
boards
  hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init
  hw/nvram/eeprom_at24c: Add init_rom field and at24c_eeprom_init_rom
helper
  hw/arm/aspeed: Add aspeed_eeprom.c
  hw/nvram/eeprom_at24c: Make reset behavior more like hardware

 hw/arm/aspeed.c | 107 ++--
 hw/arm/aspeed_eeprom.c  |  51 +++
 hw/arm/aspeed_eeprom.h  |  11 
 hw/arm/meson.build  |   1 +
 hw/arm/npcm7xx_boards.c |  20 ++
 hw/nvram/eeprom_at24c.c |  59 ++
 include/hw/nvram/eeprom_at24c.h |  12 
 7 files changed, 174 insertions(+), 87 deletions(-)
 create mode 100644 hw/arm/aspeed_eeprom.c
 create mode 100644 hw/arm/aspeed_eeprom.h
 create mode 100644 include/hw/nvram/eeprom_at24c.h

-- 
2.39.0




Re: [PATCH 6/6] hw/arm/aspeed: Init fby35 BMC FRUID EEPROM

2023-01-16 Thread Peter Delevoryas
On Mon, Jan 16, 2023 at 01:30:19PM +0100, Philippe Mathieu-Daudé wrote:
> On 14/1/23 18:01, Peter Delevoryas wrote:
> > Signed-off-by: Peter Delevoryas 
> > ---
> >   hw/arm/aspeed.c | 49 +
> >   1 file changed, 49 insertions(+)
> > 
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > index c929c61d582a..4ac8ff11a835 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -922,6 +922,52 @@ static void bletchley_bmc_i2c_init(AspeedMachineState 
> > *bmc)
> >   i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67);
> >   }
> > +static const uint8_t fby35_bmc_fruid[] = {
> [...]
> 
> > +};
> > +
> >   static void fby35_i2c_init(AspeedMachineState *bmc)
> >   {
> >   AspeedSoCState *soc = >soc;
> > @@ -1363,6 +1409,9 @@ static void fby35_reset(MachineState *state, 
> > ShutdownCause reason)
> >   object_property_set_bool(OBJECT(gpio), "gpioB3", false, _fatal);
> >   object_property_set_bool(OBJECT(gpio), "gpioB4", false, _fatal);
> >   object_property_set_bool(OBJECT(gpio), "gpioB5", false, _fatal);
> > +
> > +at24c_eeprom_write(aspeed_i2c_get_bus(>soc.i2c, 11),
> > +   0x54, 0, fby35_bmc_fruid, sizeof(fby35_bmc_fruid));
> 
> Why transfer the prom content on the i2c bus at each reset?
> 
> In particular this looks wrong if the prom is initialized with a 'drive'
> block backend (using -global).

Yeah, it looks like this might not be the right way to model it. I'm going
to try Cedric's suggestions.

> 
> >   }
> 
> 



Re: [PATCH 2/6] hw/arm/aspeed: Remove local copy of at24c_eeprom_init

2023-01-16 Thread Peter Delevoryas
On Mon, Jan 16, 2023 at 01:24:36PM +0100, Philippe Mathieu-Daudé wrote:
> On 14/1/23 18:01, Peter Delevoryas wrote:
> > Signed-off-by: Peter Delevoryas 
> > ---
> >   hw/arm/aspeed.c | 10 +-
> >   1 file changed, 1 insertion(+), 9 deletions(-)
> 
> > -static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
> > -{
> > -I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
> > -DeviceState *dev = DEVICE(i2c_dev);
> > -
> > -qdev_prop_set_uint32(dev, "rom-size", rsize);
> > -i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> > -}
> 
> Why not squash in previous commit as 'extract helper' change?

+1, I'll squash this.

> 
> Anyhow,
> Reviewed-by: Philippe Mathieu-Daudé 
> 
> 



Re: [PATCH 1/6] hw/nvram/eeprom_at24c: Add header w/ init helper

2023-01-16 Thread Peter Delevoryas
On Mon, Jan 16, 2023 at 01:23:01PM +0100, Philippe Mathieu-Daudé wrote:
> On 14/1/23 18:01, Peter Delevoryas wrote:
> > Signed-off-by: Peter Delevoryas 
> > ---
> >   hw/nvram/eeprom_at24c.c | 10 ++
> >   include/hw/nvram/eeprom_at24c.h | 10 ++
> >   2 files changed, 20 insertions(+)
> >   create mode 100644 include/hw/nvram/eeprom_at24c.h
> 
> > +void at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
> > +{
> > +I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", address);
> 
> Please use the type definition: TYPE_AT24C_EE.
> 
> > +DeviceState *dev = DEVICE(i2c_dev);
> > +
> > +qdev_prop_set_uint32(dev, "rom-size", rom_size);
> > +i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
> 
> Although the allocated object is somehow reachable from the i2c bus
> object, it would be simpler to deallocate allowing the parent to keep
> a reference to it. So consider this prototype instead:
> 
>   I2CSlave *at24c_eeprom_create(I2CBus *bus, uint8_t address,
> uint32_t rom_size);
> 

Oh ok, yeah that sounds good. In this case, if I let the parent keep a
reference, maybe I shouldn't use i2c_slave_realize_and_unref, and just use
qdev_realize/etc (to avoid the unref?). I'll try just returning the pointer
from the function to start with though.

> > +}



Re: [PATCH 6/6] hw/arm/aspeed: Init fby35 BMC FRUID EEPROM

2023-01-16 Thread Peter Delevoryas
On Mon, Jan 16, 2023 at 01:42:48PM +0100, Cédric Le Goater wrote:
> On 1/14/23 18:01, Peter Delevoryas wrote:
> > Signed-off-by: Peter Delevoryas 
> > ---
> >   hw/arm/aspeed.c | 49 +
> >   1 file changed, 49 insertions(+)
> > 
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> > index c929c61d582a..4ac8ff11a835 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -922,6 +922,52 @@ static void bletchley_bmc_i2c_init(AspeedMachineState 
> > *bmc)
> >   i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67);
> >   }
> > +static const uint8_t fby35_bmc_fruid[] = {
> > +0x01, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0xf1, 0x01, 0x0c, 0x00, 0x36,
> > +0xe6, 0xd0, 0xc6, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2, 0x42, 0x4d,
> > +0x43, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x4d, 0x6f,
> > +0x64, 0x75, 0x6c, 0x65, 0xcd, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xce, 0x58, 0x58, 0x58, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc3, 0x31, 0x2e,
> > +0x30, 0xc9, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc1, 0x39, 0x01, 0x0c, 0x00, 0xc6,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2, 0x59, 0x6f, 0x73, 0x65, 0x6d,
> > +0x69, 0x74, 0x65, 0x20, 0x56, 0x33, 0x2e, 0x35, 0x20, 0x45, 0x56, 0x54,
> > +0x32, 0xce, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0xc4, 0x45, 0x56, 0x54, 0x32, 0xcd, 0x58, 0x58,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc7,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc3, 0x31, 0x2e, 0x30, 0xc9,
> > +0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc8, 0x43, 0x6f,
> > +0x6e, 0x66, 0x69, 0x67, 0x20, 0x41, 0xc1, 0x45, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> > +};
> 
> 
> I would introduce a new aspeed_eeprom.c file for these definitions because
> each machine could have its own set of eeproms and aspeed.c is already big
> enough.

+1

> 
> >   static void fby35_i2c_init(AspeedMachineState *bmc)
> >   {
> >   AspeedSoCState *soc = >soc;
> > @@ -1363,6 +1409,9 @@ static void fby35_reset(MachineState *state, 
> > ShutdownCause reason)
> >   object_property_set_bool(OBJECT(gpio), "gpioB3", false, _fatal);
> >   obje

Re: [PATCH 0/6] hw/nvram/eeprom_at24c: Cleanup + FRUID EEPROM init example

2023-01-14 Thread Peter Delevoryas
On Sat, Jan 14, 2023 at 09:01:45AM -0800, Peter Delevoryas wrote:
> This cleans up some of the code we have creating at24c-eeprom objects in the
> Aspeed and Nuvoton files, and adds an example of how to initialize a FRUID
> EEPROM with static data using I2C transfers.
> 
> Initially I was going to propose a patch to update the at24c-eeprom realize
> function to incorporate static data, but then I realized I could just
> accomplish the same thing using i2c_send in board reset. The patch at the end
> demonstrates this.

1. I messed up Joel's email on this thread, sorry about that.
2. I forgot to post the output of the test I used to verify this:

qemu-system-aarch64 -machine fby35-bmc -nographic -mtdblock flash-fby35
...
root@bmc-oob:~# fruid-util bmc

FRU Information   : BMC
---   : --
Board Mfg Date: Mon Jan 10 21:42:00 2022
Board Mfg : XX
Board Product : BMC Storage Module
Board Serial  : X
Board Part Number : XX
Board FRU ID  : 1.0
Board Custom Data 1   : X
Board Custom Data 2   : XX
Product Manufacturer  : XX
Product Name  : Yosemite V3.5 EVT2
Product Part Number   : XX
Product Version   : EVT2
Product Serial: X
Product Asset Tag : XXX
Product FRU ID: 1.0
Product Custom Data 1 : X
Product Custom Data 2 : Config A

A reference flash-fby35 image can be found here:

https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd

> 
> Thanks,
> Peter
> 
> Peter Delevoryas (6):
>   hw/nvram/eeprom_at24c: Add header w/ init helper
>   hw/arm/aspeed: Remove local copy of at24c_eeprom_init
>   hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init
>   hw/arm/npcm7xx: Remove local copy of at24c_eeprom_init
>   hw/nvram/eeprom_at24c: Add I2C write helper
>   hw/arm/aspeed: Init fby35 BMC FRUID EEPROM
> 
>  hw/arm/aspeed.c | 154 +++-
>  hw/arm/npcm7xx_boards.c |  20 ++---
>  hw/nvram/eeprom_at24c.c |  25 ++
>  include/hw/nvram/eeprom_at24c.h |  12 +++
>  4 files changed, 135 insertions(+), 76 deletions(-)
>  create mode 100644 include/hw/nvram/eeprom_at24c.h
> 
> -- 
> 2.39.0
> 
> 



[PATCH 3/6] hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init

2023-01-14 Thread Peter Delevoryas
Signed-off-by: Peter Delevoryas 
---
 hw/arm/aspeed.c | 95 ++---
 1 file changed, 43 insertions(+), 52 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1f9799d4321e..c929c61d582a 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -660,15 +660,6 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
   eeprom_buf);
 }
 
-static void aspeed_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void fp5280g2_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
@@ -701,7 +692,7 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 AspeedSoCState *soc = >soc;
 I2CSlave *i2c_mux;
 
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 0), 0x51, 32 * KiB);
 
 create_pca9552(soc, 3, 0x61);
 
@@ -714,9 +705,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4a);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x52, 64 * KiB);
 create_pca9552(soc, 4, 0x60);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5), TYPE_TMP105,
@@ -727,8 +718,8 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 create_pca9552(soc, 5, 0x61);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 5),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6), TYPE_TMP105,
  0x48);
@@ -738,10 +729,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
  0x4b);
 i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 6),
   "pca9546", 0x70);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
-aspeed_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 0), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x51, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 2), 0x50, 64 * KiB);
+at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 3), 0x51, 64 * KiB);
 
 create_pca9552(soc, 7, 0x30);
 create_pca9552(soc, 7, 0x31);
@@ -754,15 +745,15 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 7), "max31785", 
0x52);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 7), 0x51, 64 * KiB);
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x48);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 8), TYPE_TMP105,
  0x4a);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x50, 64 * KiB);
+at24c_eeprom_init(aspeed_i2c_get_bus(>i2c, 8), 0x51, 64 * KiB);
 create_pca9552(soc, 8, 0x60);
 create_pca9552(soc, 8, 0x61);
 /* Bus 8: ucd90320@11 */
@@ -771,11 +762,11 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
 
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423", 0x4c);
 i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 9), "tmp423", 0x4d);
-aspeed_eeprom_init(aspeed_i2c_get_bus(>i2c, 9), 0x50, 128 *

[PATCH 5/6] hw/nvram/eeprom_at24c: Add I2C write helper

2023-01-14 Thread Peter Delevoryas
Signed-off-by: Peter Delevoryas 
---
 hw/nvram/eeprom_at24c.c | 15 +++
 include/hw/nvram/eeprom_at24c.h |  2 ++
 2 files changed, 17 insertions(+)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 0c27eae2b354..69565a420c28 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -10,6 +10,7 @@
 #include "qemu/osdep.h"
 
 #include "qapi/error.h"
+#include "qemu/bitops.h"
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
 #include "hw/nvram/eeprom_at24c.h"
@@ -138,6 +139,20 @@ void at24c_eeprom_init(I2CBus *bus, uint8_t address, 
uint32_t rom_size)
 i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
 }
 
+void at24c_eeprom_write(I2CBus *bus, uint8_t address, uint16_t offset,
+const uint8_t *buf, uint32_t len)
+{
+int i;
+
+i2c_start_send(bus, address);
+i2c_send(bus, extract16(offset, 8, 8));
+i2c_send(bus, extract16(offset, 0, 8));
+for (i = 0; i < len; i++) {
+i2c_send(bus, buf[i]);
+}
+i2c_end_transfer(bus);
+}
+
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
index 9d9cf212757c..bbca73a07ad1 100644
--- a/include/hw/nvram/eeprom_at24c.h
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -6,5 +6,7 @@
 #include "hw/i2c/i2c.h"
 
 void at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
+void at24c_eeprom_write(I2CBus *bus, uint8_t address, uint16_t offset,
+const uint8_t *buf, uint32_t len);
 
 #endif
-- 
2.39.0




[PATCH 0/6] hw/nvram/eeprom_at24c: Cleanup + FRUID EEPROM init example

2023-01-14 Thread Peter Delevoryas
This cleans up some of the code we have creating at24c-eeprom objects in the
Aspeed and Nuvoton files, and adds an example of how to initialize a FRUID
EEPROM with static data using I2C transfers.

Initially I was going to propose a patch to update the at24c-eeprom realize
function to incorporate static data, but then I realized I could just
accomplish the same thing using i2c_send in board reset. The patch at the end
demonstrates this.

Thanks,
Peter

Peter Delevoryas (6):
  hw/nvram/eeprom_at24c: Add header w/ init helper
  hw/arm/aspeed: Remove local copy of at24c_eeprom_init
  hw/arm/aspeed: Replace aspeed_eeprom_init with at24c_eeprom_init
  hw/arm/npcm7xx: Remove local copy of at24c_eeprom_init
  hw/nvram/eeprom_at24c: Add I2C write helper
  hw/arm/aspeed: Init fby35 BMC FRUID EEPROM

 hw/arm/aspeed.c | 154 +++-
 hw/arm/npcm7xx_boards.c |  20 ++---
 hw/nvram/eeprom_at24c.c |  25 ++
 include/hw/nvram/eeprom_at24c.h |  12 +++
 4 files changed, 135 insertions(+), 76 deletions(-)
 create mode 100644 include/hw/nvram/eeprom_at24c.h

-- 
2.39.0




[PATCH 4/6] hw/arm/npcm7xx: Remove local copy of at24c_eeprom_init

2023-01-14 Thread Peter Delevoryas
Signed-off-by: Peter Delevoryas 
---
 hw/arm/npcm7xx_boards.c | 20 +---
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 6bc6f5d2fe29..9b31207a06e9 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -21,6 +21,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -140,17 +141,6 @@ static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, 
uint32_t num)
 return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
 }
 
-static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
-  uint32_t rsize)
-{
-I2CBus *i2c_bus = npcm7xx_i2c_get_bus(soc, bus);
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, i2c_bus, _abort);
-}
-
 static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
   NPCM7xxState *soc, const int *fan_counts)
 {
@@ -253,8 +243,8 @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x5c);
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x5c);
 
-at24c_eeprom_init(soc, 9, 0x55, 8192);
-at24c_eeprom_init(soc, 10, 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 9), 0x55, 8192);
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 10), 0x55, 8192);
 
 /*
  * i2c-11:
@@ -360,7 +350,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), TYPE_PCA9548, 0x77);
 
-at24c_eeprom_init(soc, 4, 0x50, 8192); /* mbfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 4), 0x50, 8192); /* mbfru */
 
 i2c_mux = i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 13),
   TYPE_PCA9548, 0x77);
@@ -371,7 +361,7 @@ static void kudo_bmc_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 4), "tmp105", 0x48);
 i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), "tmp105", 0x49);
 
-at24c_eeprom_init(soc, 14, 0x55, 8192); /* bmcfru */
+at24c_eeprom_init(npcm7xx_i2c_get_bus(soc, 14), 0x55, 8192); /* bmcfru */
 
 /* TODO: Add remaining i2c devices. */
 }
-- 
2.39.0




[PATCH 2/6] hw/arm/aspeed: Remove local copy of at24c_eeprom_init

2023-01-14 Thread Peter Delevoryas
Signed-off-by: Peter Delevoryas 
---
 hw/arm/aspeed.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef729f..1f9799d4321e 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -17,6 +17,7 @@
 #include "hw/i2c/i2c_mux_pca954x.h"
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/misc/pca9552.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/sensor/tmp105.h"
 #include "hw/misc/led.h"
 #include "hw/qdev-properties.h"
@@ -429,15 +430,6 @@ static void aspeed_machine_init(MachineState *machine)
 arm_load_kernel(ARM_CPU(first_cpu), machine, _board_binfo);
 }
 
-static void at24c_eeprom_init(I2CBus *bus, uint8_t addr, uint32_t rsize)
-{
-I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", addr);
-DeviceState *dev = DEVICE(i2c_dev);
-
-qdev_prop_set_uint32(dev, "rom-size", rsize);
-i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
-}
-
 static void palmetto_bmc_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
-- 
2.39.0




[PATCH 6/6] hw/arm/aspeed: Init fby35 BMC FRUID EEPROM

2023-01-14 Thread Peter Delevoryas
Signed-off-by: Peter Delevoryas 
---
 hw/arm/aspeed.c | 49 +
 1 file changed, 49 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c929c61d582a..4ac8ff11a835 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -922,6 +922,52 @@ static void bletchley_bmc_i2c_init(AspeedMachineState *bmc)
 i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67);
 }
 
+static const uint8_t fby35_bmc_fruid[] = {
+0x01, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00, 0xf1, 0x01, 0x0c, 0x00, 0x36,
+0xe6, 0xd0, 0xc6, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2, 0x42, 0x4d,
+0x43, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x4d, 0x6f,
+0x64, 0x75, 0x6c, 0x65, 0xcd, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xce, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc3, 0x31, 0x2e,
+0x30, 0xc9, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc1, 0x39, 0x01, 0x0c, 0x00, 0xc6,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xd2, 0x59, 0x6f, 0x73, 0x65, 0x6d,
+0x69, 0x74, 0x65, 0x20, 0x56, 0x33, 0x2e, 0x35, 0x20, 0x45, 0x56, 0x54,
+0x32, 0xce, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0xc4, 0x45, 0x56, 0x54, 0x32, 0xcd, 0x58, 0x58,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc7,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc3, 0x31, 0x2e, 0x30, 0xc9,
+0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0xc8, 0x43, 0x6f,
+0x6e, 0x66, 0x69, 0x67, 0x20, 0x41, 0xc1, 0x45, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
 static void fby35_i2c_init(AspeedMachineState *bmc)
 {
 AspeedSoCState *soc = >soc;
@@ -1363,6 +1409,9 @@ static void fby35_reset(MachineState *state, 
ShutdownCause reason)
 object_property_set_bool(OBJECT(gpio), "gpioB3", false, _fatal);
 object_property_set_bool(OBJECT(gpio), "gpioB4", false, _fatal);
 object_property_set_bool(OBJECT(gpio), "gpioB5", false, _fatal);
+
+at24c_eeprom_write(aspeed_i2c_get_bus(>soc.i2c, 11),
+   0x54, 0, fby35_bmc_fruid, sizeof(fby35_bmc_fruid));
 }
 
 static void aspeed_machine_fby35_class_init(ObjectClass *oc, void *data)
-- 
2.39.0




[PATCH 1/6] hw/nvram/eeprom_at24c: Add header w/ init helper

2023-01-14 Thread Peter Delevoryas
Signed-off-by: Peter Delevoryas 
---
 hw/nvram/eeprom_at24c.c | 10 ++
 include/hw/nvram/eeprom_at24c.h | 10 ++
 2 files changed, 20 insertions(+)
 create mode 100644 include/hw/nvram/eeprom_at24c.h

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 2d4d8b952f38..0c27eae2b354 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -12,6 +12,7 @@
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
+#include "hw/nvram/eeprom_at24c.h"
 #include "hw/qdev-properties.h"
 #include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
@@ -128,6 +129,15 @@ int at24c_eeprom_send(I2CSlave *s, uint8_t data)
 return 0;
 }
 
+void at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size)
+{
+I2CSlave *i2c_dev = i2c_slave_new("at24c-eeprom", address);
+DeviceState *dev = DEVICE(i2c_dev);
+
+qdev_prop_set_uint32(dev, "rom-size", rom_size);
+i2c_slave_realize_and_unref(i2c_dev, bus, _abort);
+}
+
 static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
 {
 EEPROMState *ee = AT24C_EE(dev);
diff --git a/include/hw/nvram/eeprom_at24c.h b/include/hw/nvram/eeprom_at24c.h
new file mode 100644
index ..9d9cf212757c
--- /dev/null
+++ b/include/hw/nvram/eeprom_at24c.h
@@ -0,0 +1,10 @@
+/* Copyright (c) Meta Platforms, Inc. and affiliates. */
+
+#ifndef EEPROM_AT24C_H
+#define EEPROM_AT24C_H
+
+#include "hw/i2c/i2c.h"
+
+void at24c_eeprom_init(I2CBus *bus, uint8_t address, uint32_t rom_size);
+
+#endif
-- 
2.39.0




Re: [PATCH v4 1/1] python/machine: Fix AF_UNIX path too long on macOS

2023-01-10 Thread Peter Delevoryas
On Tue, Jan 10, 2023 at 06:18:29PM -0500, John Snow wrote:
> On Tue, Jan 10, 2023 at 3:34 AM Peter Delevoryas  wrote:
> >
> > On macOS, private $TMPDIR's are the default. These $TMPDIR's are
> > generated from a user's unix UID and UUID [1], which can create a
> > relatively long path:
> >
> > /var/folders/d7/rz20f6hd709c1ty8f6_6y_z4gn/T/
> >
> > QEMU's avocado tests create a temporary directory prefixed by
> > "avo_qemu_sock_", and create QMP sockets within _that_ as well.
> > The QMP socket is unnecessarily long, because a temporary directory
> > is created for every QEMUMachine object.
> >
> > /avo_qemu_sock_uh3w_dgc/qemu-37331-10bacf110-monitor.sock
> >
> > The path limit for unix sockets on macOS is 104: [2]
> >
> > /*
> >  * [XSI] Definitions for UNIX IPC domain.
> >  */
> > struct  sockaddr_un {
> > unsigned char   sun_len;/* sockaddr len including null */
> > sa_family_t sun_family; /* [XSI] AF_UNIX */
> > charsun_path[104];  /* [XSI] path name (gag) */
> > };
> >
> > This results in avocado tests failing on macOS because the QMP unix
> > socket can't be created, because the path is too long:
> >
> > ERROR| Failed to establish connection: OSError: AF_UNIX path too long
> >
> > This change resolves by reducing the size of the socket directory prefix
> > and the suffix on the QMP and console socket names.
> >
> > The result is paths like this:
> >
> > pdel@pdel-mbp:/var/folders/d7/rz20f6hd709c1ty8f6_6y_z4gn/T
> > $ tree qemu*
> > qemu_df4evjeq
> > qemu_jbxel3gy
> > qemu_ml9s_gg7
> > qemu_oc7h7f3u
> > qemu_oqb1yf97
> > ├── 10a004050.con
> > └── 10a004050.qmp
> >
> > [1] 
> > https://apple.stackexchange.com/questions/353832/why-is-mac-osx-temp-directory-in-weird-path
> > [2] 
> > /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include/sys/un.h
> >
> > Signed-off-by: Peter Delevoryas 
> 
> I'm tentatively staging this with a benefit-of-the-doubt [1] -- my
> tests are still running -- but I do have a question:
> 
> > ---
> >  python/qemu/machine/machine.py | 6 +++---
> >  tests/avocado/avocado_qemu/__init__.py | 2 +-
> >  2 files changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
> > index 748a0d807c9d..d70977378305 100644
> > --- a/python/qemu/machine/machine.py
> > +++ b/python/qemu/machine/machine.py
> > @@ -157,7 +157,7 @@ def __init__(self,
> >  self._wrapper = wrapper
> >  self._qmp_timer = qmp_timer
> >
> > -self._name = name or f"qemu-{os.getpid()}-{id(self):02x}"
> > +self._name = name or f"{id(self):x}"
> 
> Why is it safe to not differentiate based on the process ID?
> 
> ... I suppose the thinking is: by default, in machine.py, this is a
> temp dir created by tempfile.mkdtemp which will be unique per-process.
> I suppose there's no protection against a caller supplying the same
> tempdir (or sockdir) to multiple instances, but I suppose in those
> cases we get to argue that "Well, don't do that, then."
> 
> Does that sound about right?

Yeah, I think that's it

> 
> --js
> 
> [1] staged @ https://gitlab.com/jsnow/qemu/-/commits/python
> 
> 
> >  self._temp_dir: Optional[str] = None
> >  self._base_temp_dir = base_temp_dir
> >  self._sock_dir = sock_dir
> > @@ -167,7 +167,7 @@ def __init__(self,
> >  self._monitor_address = monitor_address
> >  else:
> >  self._monitor_address = os.path.join(
> > -self.sock_dir, f"{self._name}-monitor.sock"
> > +self.sock_dir, f"{self._name}.qmp"
> >  )
> >
> >  self._console_log_path = console_log
> > @@ -192,7 +192,7 @@ def __init__(self,
> >  self._console_set = False
> >  self._console_device_type: Optional[str] = None
> >  self._console_address = os.path.join(
> > -self.sock_dir, f"{self._name}-console.sock"
> > +self.sock_dir, f"{self._name}.con"
> >  )
> >  self._console_socket: Optional[socket.socket] = None
> >  self._remove_files: List[str] = []
> > diff --git a/tests/avocado/avocado_qemu/__init__.py 
> > b/tests/avocado/avocado_qemu/__init__.py
> > index 910f3ba1eab8..25a546842fab 100644
> > --- a/tests/avocado/avocado_qemu/__init__.py
> > +++ b/tests/avocado/avocado_qemu/__init__.py
> > @@ -306,7 +306,7 @@ def require_netdev(self, netdevname):
> >  self.cancel('no support for user networking')
> >
> >  def _new_vm(self, name, *args):
> > -self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")
> > +self._sd = tempfile.TemporaryDirectory(prefix="qemu_")
> >  vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir,
> >   sock_dir=self._sd.name, log_dir=self.logdir)
> >  self.log.debug('QEMUMachine "%s" created', name)
> > --
> > 2.39.0
> >
> >
> 



Re: [PATCH v5 0/1] python/machine: Fix AF_UNIX path too long

2023-01-10 Thread Peter Delevoryas
On Tue, Jan 10, 2023 at 09:38:38AM +0100, Philippe Mathieu-Daudé wrote:
> On 10/1/23 09:29, Peter Delevoryas wrote:
> 
> > $ make check-avocado
> 
> > Avocado crashed: TypeError: cannot pickle '_thread.RLock' object
> 
> Yeah... you have to pick Cleber's patches from
> https://gitlab.com/cleber.gnu/qemu/-/commits/WIP/tests_fixes
> and run as:
> 
> $ TMPDIR=/tmp avocado run --test-runner=nrunner ...

I guess I still get this error from `make check-avocado` on Aarch64 tests:

 (17/35) tests/avocado/replay_linux.py:ReplayLinuxAarch64.test_virt_gicv2: 
ERROR: Failed to fetch Fedora-Cloud-Base-31-1.9
.aarch64.qcow2 (Can't pickle local object 'url_download..download'). 
(0.89 s)

But `./build/tests/venv/bin/avocado run tests/avocado` worked ok.

> 
> This is tracked on the avocado project:
> https://github.com/avocado-framework/avocado/issues/5138#issuecomment-1314551148

Thanks!
- Peter

> 



[PATCH v5 1/1] python/machine: Fix AF_UNIX path too long on macOS

2023-01-10 Thread Peter Delevoryas
On macOS, private $TMPDIR's are the default. These $TMPDIR's are
generated from a user's unix UID and UUID [1], which can create a
relatively long path:

/var/folders/d7/rz20f6hd709c1ty8f6_6y_z4gn/T/

QEMU's avocado tests create a temporary directory prefixed by
"avo_qemu_sock_", and create QMP sockets within _that_ as well.
The QMP socket is unnecessarily long, because a temporary directory
is created for every QEMUMachine object.

/avo_qemu_sock_uh3w_dgc/qemu-37331-10bacf110-monitor.sock

The path limit for unix sockets on macOS is 104: [2]

/*
 * [XSI] Definitions for UNIX IPC domain.
 */
struct  sockaddr_un {
unsigned char   sun_len;/* sockaddr len including null */
sa_family_t sun_family; /* [XSI] AF_UNIX */
charsun_path[104];  /* [XSI] path name (gag) */
};

This results in avocado tests failing on macOS because the QMP unix
socket can't be created, because the path is too long:

ERROR| Failed to establish connection: OSError: AF_UNIX path too long

This change resolves by reducing the size of the socket directory prefix
and the suffix on the QMP and console socket names.

The result is paths like this:

pdel@pdel-mbp:/var/folders/d7/rz20f6hd709c1ty8f6_6y_z4gn/T
$ tree qemu*
qemu_df4evjeq
qemu_jbxel3gy
qemu_ml9s_gg7
qemu_oc7h7f3u
qemu_oqb1yf97
├── 10a004050.con
└── 10a004050.qmp

[1] 
https://apple.stackexchange.com/questions/353832/why-is-mac-osx-temp-directory-in-weird-path
[2] /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include/sys/un.h

Signed-off-by: Peter Delevoryas 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Philippe Mathieu-Daudé 
---
 python/qemu/machine/machine.py | 6 +++---
 tests/avocado/avocado_qemu/__init__.py | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index 748a0d807c9d..d70977378305 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -157,7 +157,7 @@ def __init__(self,
 self._wrapper = wrapper
 self._qmp_timer = qmp_timer
 
-self._name = name or f"qemu-{os.getpid()}-{id(self):02x}"
+self._name = name or f"{id(self):x}"
 self._temp_dir: Optional[str] = None
 self._base_temp_dir = base_temp_dir
 self._sock_dir = sock_dir
@@ -167,7 +167,7 @@ def __init__(self,
 self._monitor_address = monitor_address
 else:
 self._monitor_address = os.path.join(
-self.sock_dir, f"{self._name}-monitor.sock"
+self.sock_dir, f"{self._name}.qmp"
 )
 
 self._console_log_path = console_log
@@ -192,7 +192,7 @@ def __init__(self,
 self._console_set = False
 self._console_device_type: Optional[str] = None
 self._console_address = os.path.join(
-self.sock_dir, f"{self._name}-console.sock"
+self.sock_dir, f"{self._name}.con"
 )
 self._console_socket: Optional[socket.socket] = None
 self._remove_files: List[str] = []
diff --git a/tests/avocado/avocado_qemu/__init__.py 
b/tests/avocado/avocado_qemu/__init__.py
index 910f3ba1eab8..25a546842fab 100644
--- a/tests/avocado/avocado_qemu/__init__.py
+++ b/tests/avocado/avocado_qemu/__init__.py
@@ -306,7 +306,7 @@ def require_netdev(self, netdevname):
 self.cancel('no support for user networking')
 
 def _new_vm(self, name, *args):
-self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")
+self._sd = tempfile.TemporaryDirectory(prefix="qemu_")
 vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir,
  sock_dir=self._sd.name, log_dir=self.logdir)
 self.log.debug('QEMUMachine "%s" created', name)
-- 
2.39.0




[PATCH v5 0/1] python/machine: Fix AF_UNIX path too long

2023-01-10 Thread Peter Delevoryas
v1: https://lore.kernel.org/qemu-devel/20220705214659.73369-1-pe...@pjd.dev/
v2: https://lore.kernel.org/qemu-devel/20220716173434.17183-1-pe...@pjd.dev/
v3:
- Changed QEMUMachine._name to f"{id(self):x}". Suggestion was to do
  f"{id(self):02x}", but the id's look like they are probably just the
  object address (8-byte pointer), so the "02" had no effect.
- Changed QMP socket name suffix from "-monitor.sock" to ".qmp".
- Changed console socket name suffix from "-console.sock" to ".con".
v4:
- Just resending v3 after rebasing from a long time ago
v5:
- I forgot to disable the VPN on my laptop before sending the v4 series,
  and I always have very mysterious errors and/or delays when I send email
  through the VPN because our security team doesn't allow split tunneling.
- I also forgot to include the reviewed-by tags. Daniel reviewed v3,
  Phil reviewed v4.

I tried to run `make check-avocado` before sending again, but it looks like
there is some other issue. Probably related to the python version I have (I
have like 5 different Python versions installed on my work laptop).

Thanks,
Peter

$ make check-avocado
changing dir to build for /Library/Developer/CommandLineTools/usr/bin/make 
"check-avocado"...
  GIT ui/keycodemapdb tests/fp/berkeley-testfloat-3 
tests/fp/berkeley-softfloat-3 dtc
  VENV/Users/pdel/qemu/build/tests/venv
  VENVPIP install -e /Users/pdel/qemu/python/
  VENVPIP install -r /Users/pdel/qemu/tests/requirements.txt
  MKDIR   /Users/pdel/qemu/build/tests/results
  AVOCADO Downloading avocado tests VM image for aarch64
The image was downloaded:
Provider Version Architecture File
fedora   31  aarch64  
/Users/pdel/avocado/data/cache/by_location/4f156e531446a679cbfe13caef8b7c9f9f79aafa/Fedora-C
loud-Base-31-1.9.aarch64.qcow2
  AVOCADO tests/avocado
Fetching asset from 
tests/avocado/boot_linux_console.py:BootLinuxConsole.test_aarch64_raspi3_atf
Fetching asset from 
tests/avocado/boot_xen.py:BootXen.test_arm64_xen_411_and_dom0
Fetching asset from 
tests/avocado/boot_xen.py:BootXen.test_arm64_xen_414_and_dom0
Fetching asset from 
tests/avocado/boot_xen.py:BootXen.test_arm64_xen_415_and_dom0
Fetching asset from 
tests/avocado/machine_aarch64_virt.py:Aarch64VirtMachine.test_alpine_virt_tcg_gic_max
Fetching asset from 
tests/avocado/machine_aarch64_virt.py:Aarch64VirtMachine.test_aarch64_virt
Fetching asset from 
tests/avocado/replay_kernel.py:ReplayKernelNormal.test_aarch64_virt
Fetching asset from 
tests/avocado/reverse_debugging.py:ReverseDebugging_AArch64.test_aarch64_virt
JOB ID : 18a949ed9150e22d6ecea69b99ede1ded17233f4
JOB LOG: 
/Users/pdel/qemu/build/tests/results/job-2023-01-10T00.03-18a949e/job.log

Avocado crashed: TypeError: cannot pickle '_thread.RLock' object

Peter Delevoryas (1):
  python/machine: Fix AF_UNIX path too long on macOS

 python/qemu/machine/machine.py | 6 +++---
 tests/avocado/avocado_qemu/__init__.py | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

-- 
2.39.0




[PATCH v4 0/1] python/machine: Fix AF_UNIX path too long

2023-01-10 Thread Peter Delevoryas
v1: https://lore.kernel.org/qemu-devel/20220705214659.73369-1-pe...@pjd.dev/
v2: https://lore.kernel.org/qemu-devel/20220716173434.17183-1-pe...@pjd.dev/
v3:
- Changed QEMUMachine._name to f"{id(self):x}". Suggestion was to do
  f"{id(self):02x}", but the id's look like they are probably just the
  object address (8-byte pointer), so the "02" had no effect.
- Changed QMP socket name suffix from "-monitor.sock" to ".qmp".
- Changed console socket name suffix from "-console.sock" to ".con".
v4:
- Just resending v3 after rebasing from a long time ago

I tried to run `make check-avocado` before sending again, but it looks like
there is some other issue. Probably related to the python version I have (I
have like 5 different Python versions installed on my work laptop).

Thanks,
Peter

$ make check-avocado
changing dir to build for /Library/Developer/CommandLineTools/usr/bin/make 
"check-avocado"...
  GIT ui/keycodemapdb tests/fp/berkeley-testfloat-3 
tests/fp/berkeley-softfloat-3 dtc
  VENV/Users/pdel/qemu/build/tests/venv
  VENVPIP install -e /Users/pdel/qemu/python/
  VENVPIP install -r /Users/pdel/qemu/tests/requirements.txt
  MKDIR   /Users/pdel/qemu/build/tests/results
  AVOCADO Downloading avocado tests VM image for aarch64
The image was downloaded:
Provider Version Architecture File
fedora   31  aarch64  
/Users/pdel/avocado/data/cache/by_location/4f156e531446a679cbfe13caef8b7c9f9f79aafa/Fedora-C
loud-Base-31-1.9.aarch64.qcow2
  AVOCADO tests/avocado
Fetching asset from 
tests/avocado/boot_linux_console.py:BootLinuxConsole.test_aarch64_raspi3_atf
Fetching asset from 
tests/avocado/boot_xen.py:BootXen.test_arm64_xen_411_and_dom0
Fetching asset from 
tests/avocado/boot_xen.py:BootXen.test_arm64_xen_414_and_dom0
Fetching asset from 
tests/avocado/boot_xen.py:BootXen.test_arm64_xen_415_and_dom0
Fetching asset from 
tests/avocado/machine_aarch64_virt.py:Aarch64VirtMachine.test_alpine_virt_tcg_gic_max
Fetching asset from 
tests/avocado/machine_aarch64_virt.py:Aarch64VirtMachine.test_aarch64_virt
Fetching asset from 
tests/avocado/replay_kernel.py:ReplayKernelNormal.test_aarch64_virt
Fetching asset from 
tests/avocado/reverse_debugging.py:ReverseDebugging_AArch64.test_aarch64_virt
JOB ID : 18a949ed9150e22d6ecea69b99ede1ded17233f4
JOB LOG: 
/Users/pdel/qemu/build/tests/results/job-2023-01-10T00.03-18a949e/job.log

Avocado crashed: TypeError: cannot pickle '_thread.RLock' object

Peter Delevoryas (1):
  python/machine: Fix AF_UNIX path too long on macOS

 python/qemu/machine/machine.py | 6 +++---
 tests/avocado/avocado_qemu/__init__.py | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

-- 
2.39.0




[PATCH v4 1/1] python/machine: Fix AF_UNIX path too long on macOS

2023-01-10 Thread Peter Delevoryas
On macOS, private $TMPDIR's are the default. These $TMPDIR's are
generated from a user's unix UID and UUID [1], which can create a
relatively long path:

/var/folders/d7/rz20f6hd709c1ty8f6_6y_z4gn/T/

QEMU's avocado tests create a temporary directory prefixed by
"avo_qemu_sock_", and create QMP sockets within _that_ as well.
The QMP socket is unnecessarily long, because a temporary directory
is created for every QEMUMachine object.

/avo_qemu_sock_uh3w_dgc/qemu-37331-10bacf110-monitor.sock

The path limit for unix sockets on macOS is 104: [2]

/*
 * [XSI] Definitions for UNIX IPC domain.
 */
struct  sockaddr_un {
unsigned char   sun_len;/* sockaddr len including null */
sa_family_t sun_family; /* [XSI] AF_UNIX */
charsun_path[104];  /* [XSI] path name (gag) */
};

This results in avocado tests failing on macOS because the QMP unix
socket can't be created, because the path is too long:

ERROR| Failed to establish connection: OSError: AF_UNIX path too long

This change resolves by reducing the size of the socket directory prefix
and the suffix on the QMP and console socket names.

The result is paths like this:

pdel@pdel-mbp:/var/folders/d7/rz20f6hd709c1ty8f6_6y_z4gn/T
$ tree qemu*
qemu_df4evjeq
qemu_jbxel3gy
qemu_ml9s_gg7
qemu_oc7h7f3u
qemu_oqb1yf97
├── 10a004050.con
└── 10a004050.qmp

[1] 
https://apple.stackexchange.com/questions/353832/why-is-mac-osx-temp-directory-in-weird-path
[2] /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include/sys/un.h

Signed-off-by: Peter Delevoryas 
---
 python/qemu/machine/machine.py | 6 +++---
 tests/avocado/avocado_qemu/__init__.py | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index 748a0d807c9d..d70977378305 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -157,7 +157,7 @@ def __init__(self,
 self._wrapper = wrapper
 self._qmp_timer = qmp_timer
 
-self._name = name or f"qemu-{os.getpid()}-{id(self):02x}"
+self._name = name or f"{id(self):x}"
 self._temp_dir: Optional[str] = None
 self._base_temp_dir = base_temp_dir
 self._sock_dir = sock_dir
@@ -167,7 +167,7 @@ def __init__(self,
 self._monitor_address = monitor_address
 else:
 self._monitor_address = os.path.join(
-self.sock_dir, f"{self._name}-monitor.sock"
+self.sock_dir, f"{self._name}.qmp"
 )
 
 self._console_log_path = console_log
@@ -192,7 +192,7 @@ def __init__(self,
 self._console_set = False
 self._console_device_type: Optional[str] = None
 self._console_address = os.path.join(
-self.sock_dir, f"{self._name}-console.sock"
+self.sock_dir, f"{self._name}.con"
 )
 self._console_socket: Optional[socket.socket] = None
 self._remove_files: List[str] = []
diff --git a/tests/avocado/avocado_qemu/__init__.py 
b/tests/avocado/avocado_qemu/__init__.py
index 910f3ba1eab8..25a546842fab 100644
--- a/tests/avocado/avocado_qemu/__init__.py
+++ b/tests/avocado/avocado_qemu/__init__.py
@@ -306,7 +306,7 @@ def require_netdev(self, netdevname):
 self.cancel('no support for user networking')
 
 def _new_vm(self, name, *args):
-self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")
+self._sd = tempfile.TemporaryDirectory(prefix="qemu_")
 vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir,
  sock_dir=self._sd.name, log_dir=self.logdir)
 self.log.debug('QEMUMachine "%s" created', name)
-- 
2.39.0




Re: [PATCH v3 1/1] python/machine: Fix AF_UNIX path too long on macOS

2023-01-10 Thread Peter Delevoryas
On Mon, Jan 09, 2023 at 04:09:32PM -0500, John Snow wrote:
> On Mon, Jul 25, 2022 at 5:06 AM Daniel P. Berrangé  
> wrote:
> >
> > On Fri, Jul 22, 2022 at 11:25:08AM -0700, Peter Delevoryas wrote:
> > > On macOS, private $TMPDIR's are the default. These $TMPDIR's are
> > > generated from a user's unix UID and UUID [1], which can create a
> > > relatively long path:
> > >
> > > /var/folders/d7/rz20f6hd709c1ty8f6_6y_z4gn/T/
> > >
> > > QEMU's avocado tests create a temporary directory prefixed by
> > > "avo_qemu_sock_", and create QMP sockets within _that_ as well.
> > > The QMP socket is unnecessarily long, because a temporary directory
> > > is created for every QEMUMachine object.
> > >
> > > /avo_qemu_sock_uh3w_dgc/qemu-37331-10bacf110-monitor.sock
> > >
> > > The path limit for unix sockets on macOS is 104: [2]
> > >
> > > /*
> > >  * [XSI] Definitions for UNIX IPC domain.
> > >  */
> > > struct  sockaddr_un {
> > > unsigned char   sun_len;/* sockaddr len including null */
> > > sa_family_t sun_family; /* [XSI] AF_UNIX */
> > > charsun_path[104];  /* [XSI] path name (gag) */
> > > };
> > >
> > > This results in avocado tests failing on macOS because the QMP unix
> > > socket can't be created, because the path is too long:
> > >
> > > ERROR| Failed to establish connection: OSError: AF_UNIX path too long
> > >
> > > This change resolves by reducing the size of the socket directory prefix
> > > and the suffix on the QMP and console socket names.
> > >
> > > The result is paths like this:
> > >
> > > pdel@pdel-mbp:/var/folders/d7/rz20f6hd709c1ty8f6_6y_z4gn/T
> > > $ tree qemu*
> > > qemu_df4evjeq
> > > qemu_jbxel3gy
> > > qemu_ml9s_gg7
> > > qemu_oc7h7f3u
> > > qemu_oqb1yf97
> > > ├── 10a004050.con
> > > └── 10a004050.qmp
> > >
> > > [1] 
> > > https://apple.stackexchange.com/questions/353832/why-is-mac-osx-temp-directory-in-weird-path
> > > [2] 
> > > /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include/sys/un.h
> > >
> > > Signed-off-by: Peter Delevoryas 
> > > ---
> > >  python/qemu/machine/machine.py | 6 +++---
> > >  tests/avocado/avocado_qemu/__init__.py | 2 +-
> > >  2 files changed, 4 insertions(+), 4 deletions(-)
> >
> > Reviewed-by: Daniel P. Berrangé 
> 
> My apologies, I missed this update because it appeared in a thread
> underneath the old version.

Oh, that's ok, nice catch digging this up! I completely forgot about it, and
haven't been developing QEMU stuff on macOS in a little while

> 
> Peter, may I please ask for you to kindly re-submit this patch with an
> incremented version number?

Sure! I've resubmitted it as v4 and v5, v4 might not have been sent correctly
(I have so many problems with sending emails lol)

v4: https://lore.kernel.org/qemu-devel/20230110080756.38271-1-pe...@pjd.dev/T/#t
v5: < will probably show up on the mailing list soon >


- Peter

> 
> --js
> 



[PATCH 1/1] net/slirp: Add mfr-id and oob-eth-addr parameters

2023-01-05 Thread Peter Delevoryas
This adds mfr-id and oob-eth-addr parameters to the userspace netdev backend.

-netdev user,id=[str],mfr-id=[uint32],oob-eth-addr=[MAC address]

Signed-off-by: Peter Delevoryas 
---
 net/slirp.c   | 19 ---
 qapi/net.json |  9 -
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 2ee3f1a0d7..97c83d99f7 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -413,7 +413,8 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
   const char *vnameserver, const char *vnameserver6,
   const char *smb_export, const char *vsmbserver,
   const char **dnssearch, const char *vdomainname,
-  const char *tftp_server_name,
+  const char *tftp_server_name, uint32_t mfr_id,
+  const char *oob_eth_addr_str,
   Error **errp)
 {
 /* default settings according to historic slirp */
@@ -436,6 +437,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 int shift;
 char *end;
 struct slirp_config_str *config;
+MACAddr oob_eth_addr = {};
 
 if (!ipv4 && (vnetwork || vhost || vnameserver)) {
 error_setg(errp, "IPv4 disabled but netmask/host/dns provided");
@@ -609,6 +611,12 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 return -1;
 }
 
+if (oob_eth_addr_str &&
+net_parse_macaddr(oob_eth_addr.a, oob_eth_addr_str) < 0) {
+error_setg(errp, "'oob-eth-addr' invalid syntax for MAC address");
+return -1;
+}
+
 nc = qemu_new_net_client(_slirp_info, peer, model, name);
 
 qemu_set_info_str(nc, "net=%s,restrict=%s", inet_ntoa(net),
@@ -616,7 +624,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 
 s = DO_UPCAST(SlirpState, nc, nc);
 
-cfg.version = SLIRP_CHECK_VERSION(4,7,0) ? 4 : 1;
+cfg.version = SLIRP_CONFIG_VERSION_MAX;
 cfg.restricted = restricted;
 cfg.in_enabled = ipv4;
 cfg.vnetwork = net;
@@ -635,6 +643,10 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 cfg.vnameserver6 = ip6_dns;
 cfg.vdnssearch = dnssearch;
 cfg.vdomainname = vdomainname;
+#if SLIRP_CONFIG_VERSION_MAX >= 5
+cfg.mfr_id = mfr_id;
+memcpy(cfg.oob_eth_addr, oob_eth_addr.a, sizeof(cfg.oob_eth_addr));
+#endif
 s->slirp = slirp_new(, _cb, s);
 QTAILQ_INSERT_TAIL(_stacks, s, entry);
 
@@ -1171,7 +1183,8 @@ int net_init_slirp(const Netdev *netdev, const char *name,
  user->bootfile, user->dhcpstart,
  user->dns, user->ipv6_dns, user->smb,
  user->smbserver, dnssearch, user->domainname,
- user->tftp_server_name, errp);
+ user->tftp_server_name, user->mfr_id,
+ user->oob_eth_addr, errp);
 
 while (slirp_configs) {
 config = slirp_configs;
diff --git a/qapi/net.json b/qapi/net.json
index 522ac582ed..7aa1ea0496 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -168,6 +168,11 @@
 #
 # @tftp-server-name: RFC2132 "TFTP server name" string (Since 3.1)
 #
+# @mfr-id: Manufacturer ID (IANA Private Enterprise Number)
+#
+# @oob-eth-addr: MAC Address allocated for an out-of-band management
+#controller, to be retrieved through NC-SI.
+#
 # Since: 1.2
 ##
 { 'struct': 'NetdevUserOptions',
@@ -193,7 +198,9 @@
 '*smbserver': 'str',
 '*hostfwd':   ['String'],
 '*guestfwd':  ['String'],
-'*tftp-server-name': 'str' } }
+'*tftp-server-name': 'str',
+'*mfr-id':'uint32',
+'*oob-eth-addr': 'str' } }
 
 ##
 # @NetdevTapOptions:
-- 
2.31.1




[PATCH 0/1] net/slirp: Add mfr-id and oob-eth-addr parameters

2023-01-05 Thread Peter Delevoryas
This adds mfr-id and oob-eth-addr parameters to the userspace netdev backend.

-netdev user,id=[str],mfr-id=[uint32],oob-eth-addr=[MAC address]

I introduced mfr-id and oob-eth-addr to slirp a while ago, as part of Slirp
config version 5, but never managed to get the options exposed in upstream QEMU
(I've just been maintaining my own patches).

This is useful for testing NC-SI OEM commands, which are critical for bringing
up the network path for lots of BMC's in data centers. So like, OpenBMC devs
would be interested in this.

I tried to submit this change a long time ago, but failed cause I wasn't sure
exactly how to gate this on the slirp version.

My strategy was actually not to use the slirp version (e.g. 4.7.0) to check for
this, but to use the slirp config version. This is different, but correct, I
think? If we don't use the slirp config version, we have to create a new slirp
release, 4.8.0. But, I don't see the point of that, because we already have a
version number exposed for the SlirpConfig.

Thanks,
Peter

Peter Delevoryas (1):
  net/slirp: Add mfr-id and oob-eth-addr parameters

 net/slirp.c   | 19 ---
 qapi/net.json |  9 -
 2 files changed, 24 insertions(+), 4 deletions(-)

-- 
2.31.1




Re: [PATCH v2 02/11] hw/watchdog/wdt_aspeed: Extend MMIO range to cover more registers

2023-01-03 Thread Peter Delevoryas
On Tue, Jan 03, 2023 at 04:48:14PM +0100, Cédric Le Goater wrote:
> On 1/3/23 16:31, Peter Delevoryas wrote:
> > On Mon, Jan 02, 2023 at 02:31:31PM +0100, Cédric Le Goater wrote:
> > > On 12/31/22 23:52, Dong, Eddie wrote:
> > > > > When booting the Zephyr demo in [1] we get:
> > > > > 
> > > > > aspeed.io: unimplemented device write (size 4, offset 0x185128, 
> > > > > value
> > > > > 0x030f1ff1) <--
> > > > > aspeed.io: unimplemented device write (size 4, offset 0x18512c, 
> > > > > value
> > > > > 0x03f1)
> > > > > 
> > > > > This corresponds to this Zephyr code [2]:
> > > > > 
> > > > > static int aspeed_wdt_init(const struct device *dev)
> > > > > {
> > > > >   const struct aspeed_wdt_config *config = dev->config;
> > > > >   struct aspeed_wdt_data *const data = dev->data;
> > > > >   uint32_t reg_val;
> > > > > 
> > > > >   /* disable WDT by default */
> > > > >   reg_val = sys_read32(config->ctrl_base + WDT_CTRL_REG);
> > > > >   reg_val &= ~WDT_CTRL_ENABLE;
> > > > >   sys_write32(reg_val, config->ctrl_base + WDT_CTRL_REG);
> > > > > 
> > > > >   sys_write32(data->rst_mask1,
> > > > >   config->ctrl_base + WDT_SW_RESET_MASK1_REG);   
> > > > > <--
> > > > >   sys_write32(data->rst_mask2,
> > > > >   config->ctrl_base + WDT_SW_RESET_MASK2_REG);
> > > > > 
> > > > >   return 0;
> > > > > }
> > > > > 
> > > > > The register definitions are [3]:
> > > > > 
> > > > > #define WDT_RELOAD_VAL_REG  0x0004
> > > > > #define WDT_RESTART_REG 0x0008
> > > > > #define WDT_CTRL_REG0x000C
> > > > > #define WDT_TIMEOUT_STATUS_REG  0x0010
> > > > > #define WDT_TIMEOUT_STATUS_CLR_REG  0x0014
> > > > > #define WDT_RESET_MASK1_REG 0x001C
> > > > > #define WDT_RESET_MASK2_REG 0x0020
> > > > > #define WDT_SW_RESET_MASK1_REG  0x0028   <--
> > > > > #define WDT_SW_RESET_MASK2_REG  0x002C
> > > > > #define WDT_SW_RESET_CTRL_REG   0x0024
> > > > > 
> > > > > Currently QEMU only cover a MMIO region of size 0x20:
> > > > > 
> > > > > #define ASPEED_WDT_REGS_MAX(0x20 / 4)
> > > > > 
> > > > > Change to map the whole 'iosize' which might be bigger, covering the 
> > > > > other
> > > > 
> > > > The root cause is that ASPEED_WDT_REGS_MAX is too small, right?
> > > > Probably the Qemu is emulating an old version of the hardware.
> > > > 
> > > > Given the meaning of ASPEED_WDT_REGS_MAX, it should be larger than 
> > > > iosize, not?
> > > > Probably ASPEED_WDT_REGS_MAX should be per device type 
> > > > (aspeed_2400/2500),
> > > 
> > > yes. We would need a new class attribute for it. Please use these values, 
> > > they
> > > should be correct.
> > > 
> > > #regsiosize
> > > 
> > > AST2400   0x18/4  0x20
> > > AST2500   0x20/4  0x20
> > 
> > I think only one additional register was added in the AST2500, bringing it 
> > to 0x1C.
> 
> yes.
> 
> > 
> > > AST2600   0x30/4  0x40
> > > AST1030   0x4C/4  0x80
> > 
> > I know the Zephyr driver for the AST1030 directly from Aspeed is claiming 
> > that
> > the iosize is 0x80, but the datasheet I have says it's only 0x40. And, that 
> > the
> > #regs would still just be 0x30/4. Afaik the AST2600 and AST1030 should have 
> > the
> > exact same peripheral.
> 
> Hmm, I see 5 extra registers in the AST1030 SoC compared to the AST2600 SoC. 
> All
> related to write protection.

Oh really? Hmmm ok, perhaps my datasheet is outdated then, I'm referencing
AST1030 A0 v0.5 from Feb 2021, which might be outdated.

Thanks, sorry for the confusion. Erg.
Peter

> 
> C.
> 



Re: [PATCH v2 02/11] hw/watchdog/wdt_aspeed: Extend MMIO range to cover more registers

2023-01-03 Thread Peter Delevoryas
On Mon, Jan 02, 2023 at 02:31:31PM +0100, Cédric Le Goater wrote:
> On 12/31/22 23:52, Dong, Eddie wrote:
> > > When booting the Zephyr demo in [1] we get:
> > > 
> > >aspeed.io: unimplemented device write (size 4, offset 0x185128, value
> > > 0x030f1ff1) <--
> > >aspeed.io: unimplemented device write (size 4, offset 0x18512c, value
> > > 0x03f1)
> > > 
> > > This corresponds to this Zephyr code [2]:
> > > 
> > >static int aspeed_wdt_init(const struct device *dev)
> > >{
> > >  const struct aspeed_wdt_config *config = dev->config;
> > >  struct aspeed_wdt_data *const data = dev->data;
> > >  uint32_t reg_val;
> > > 
> > >  /* disable WDT by default */
> > >  reg_val = sys_read32(config->ctrl_base + WDT_CTRL_REG);
> > >  reg_val &= ~WDT_CTRL_ENABLE;
> > >  sys_write32(reg_val, config->ctrl_base + WDT_CTRL_REG);
> > > 
> > >  sys_write32(data->rst_mask1,
> > >  config->ctrl_base + WDT_SW_RESET_MASK1_REG);   <--
> > >  sys_write32(data->rst_mask2,
> > >  config->ctrl_base + WDT_SW_RESET_MASK2_REG);
> > > 
> > >  return 0;
> > >}
> > > 
> > > The register definitions are [3]:
> > > 
> > >#define WDT_RELOAD_VAL_REG  0x0004
> > >#define WDT_RESTART_REG 0x0008
> > >#define WDT_CTRL_REG0x000C
> > >#define WDT_TIMEOUT_STATUS_REG  0x0010
> > >#define WDT_TIMEOUT_STATUS_CLR_REG  0x0014
> > >#define WDT_RESET_MASK1_REG 0x001C
> > >#define WDT_RESET_MASK2_REG 0x0020
> > >#define WDT_SW_RESET_MASK1_REG  0x0028   <--
> > >#define WDT_SW_RESET_MASK2_REG  0x002C
> > >#define WDT_SW_RESET_CTRL_REG   0x0024
> > > 
> > > Currently QEMU only cover a MMIO region of size 0x20:
> > > 
> > >#define ASPEED_WDT_REGS_MAX(0x20 / 4)
> > > 
> > > Change to map the whole 'iosize' which might be bigger, covering the other
> > 
> > The root cause is that ASPEED_WDT_REGS_MAX is too small, right?
> > Probably the Qemu is emulating an old version of the hardware.
> > 
> > Given the meaning of ASPEED_WDT_REGS_MAX, it should be larger than iosize, 
> > not?
> > Probably ASPEED_WDT_REGS_MAX should be per device type (aspeed_2400/2500),
> 
> yes. We would need a new class attribute for it. Please use these values, they
> should be correct.
> 
>#regsiosize
> 
> AST2400   0x18/4  0x20
> AST2500   0x20/4  0x20

I think only one additional register was added in the AST2500, bringing it to 
0x1C.

> AST2600   0x30/4  0x40
> AST1030   0x4C/4  0x80

I know the Zephyr driver for the AST1030 directly from Aspeed is claiming that
the iosize is 0x80, but the datasheet I have says it's only 0x40. And, that the
#regs would still just be 0x30/4. Afaik the AST2600 and AST1030 should have the
exact same peripheral.

Peter

> 
> 
> AFAICT, the WDT logic was changed in a compatible way with the previous 
> generation.
> 
> Thanks
> 
> C.
> 
> > while iosize is for all devices, and its initial value comes from the per 
> > device type REGS_MAX.
> > 
> > > registers. The MemoryRegionOps read/write handlers will report the 
> > > accesses
> > > as out-of-bounds guest-errors, but the next commit will report them as
> > > unimplemented.
> > > 
> > > [1] https://github.com/AspeedTech-BMC/zephyr/releases/tag/v00.01.07
> > > [2] https://github.com/AspeedTech-BMC/zephyr/commit/2e99f10ac27b
> > > [3] https://github.com/AspeedTech-
> > > BMC/zephyr/blob/v00.01.08/drivers/watchdog/wdt_aspeed.c#L31
> > > 
> > > Reviewed-by: Peter Delevoryas 
> > > Signed-off-by: Philippe Mathieu-Daudé 
> > > ---
> > >   hw/watchdog/wdt_aspeed.c | 3 ++-
> > >   1 file changed, 2 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c index
> > > 958725a1b5..eefca31ae4 100644
> > > --- a/hw/watchdog/wdt_aspeed.c
> > > +++ b/hw/watchdog/wdt_aspeed.c
> > > @@ -260,6 +260,7 @@ static void aspeed_wdt_realize(DeviceState *dev,
> > > Error **errp)  {
> > >   SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> > >   AspeedWDTState *s = ASPEED_WDT(dev);
> > > +AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(dev);
> > > 
> > >   assert(s->scu);
> > > 
> > > @@ -271,7 +272,7 @@ static void aspeed_wdt_realize(DeviceState *dev,
> > > Error **errp)
> > >   s->pclk_freq = PCLK_HZ;
> > > 
> > >   memory_region_init_io(>iomem, OBJECT(s), _wdt_ops, s,
> > > -  TYPE_ASPEED_WDT, ASPEED_WDT_REGS_MAX * 4);
> > > +  TYPE_ASPEED_WDT, awc->iosize);
> > >   sysbus_init_mmio(sbd, >iomem);
> > >   }
> > > 
> > > --
> > > 2.38.1
> > > 
> > 
> 



Re: [PATCH v2 01/11] hw/watchdog/wdt_aspeed: Rename MMIO region size as 'iosize'

2023-01-03 Thread Peter Delevoryas
On Fri, Dec 30, 2022 at 12:34:54PM +0100, Philippe Mathieu-Daudé wrote:
> Avoid confusing two different things:
> - the WDT I/O region size ('iosize')
> - at which offset the SoC map the WDT ('offset')
> While it is often the same, we can map smaller region sizes
> at larger offsets.
> 
> Here we are interested in the I/O region size, so rename as
> 'iosize'.
> 
> Reviewed-by: Peter Delevoryas 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/arm/aspeed_ast10x0.c  | 2 +-
>  hw/arm/aspeed_ast2600.c  | 2 +-
>  hw/arm/aspeed_soc.c  | 2 +-
>  hw/watchdog/wdt_aspeed.c | 8 
>  include/hw/watchdog/wdt_aspeed.h | 2 +-
>  5 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index 4d0b9b115f..122b3fd3f3 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -325,7 +325,7 @@ static void aspeed_soc_ast1030_realize(DeviceState 
> *dev_soc, Error **errp)
>  return;
>  }
>  aspeed_mmio_map(s, SYS_BUS_DEVICE(>wdt[i]), 0,
> -sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
> +sc->memmap[ASPEED_DEV_WDT] + i * awc->iosize);
>  }
>  
>  /* GPIO */
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index cd75465c2b..a79e05ddbd 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -472,7 +472,7 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
> Error **errp)
>  return;
>  }
>  aspeed_mmio_map(s, SYS_BUS_DEVICE(>wdt[i]), 0,
> -sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
> +sc->memmap[ASPEED_DEV_WDT] + i * awc->iosize);
>  }
>  
>  /* RAM */
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index b05b9dd416..2c0924d311 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -393,7 +393,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
> **errp)
>  return;
>  }
>  aspeed_mmio_map(s, SYS_BUS_DEVICE(>wdt[i]), 0,
> -sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
> +sc->memmap[ASPEED_DEV_WDT] + i * awc->iosize);
>  }
>  
>  /* RAM  */
> diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
> index d753693a2e..958725a1b5 100644
> --- a/hw/watchdog/wdt_aspeed.c
> +++ b/hw/watchdog/wdt_aspeed.c
> @@ -309,7 +309,7 @@ static void aspeed_2400_wdt_class_init(ObjectClass 
> *klass, void *data)
>  AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
>  
>  dc->desc = "ASPEED 2400 Watchdog Controller";
> -awc->offset = 0x20;
> +awc->iosize = 0x20;
>  awc->ext_pulse_width_mask = 0xff;
>  awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
>  awc->wdt_reload = aspeed_wdt_reload;
> @@ -346,7 +346,7 @@ static void aspeed_2500_wdt_class_init(ObjectClass 
> *klass, void *data)
>  AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
>  
>  dc->desc = "ASPEED 2500 Watchdog Controller";
> -awc->offset = 0x20;
> +awc->iosize = 0x20;
>  awc->ext_pulse_width_mask = 0xf;
>  awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
>  awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
> @@ -369,7 +369,7 @@ static void aspeed_2600_wdt_class_init(ObjectClass 
> *klass, void *data)
>  AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
>  
>  dc->desc = "ASPEED 2600 Watchdog Controller";
> -awc->offset = 0x40;
> +awc->iosize = 0x40;
>  awc->ext_pulse_width_mask = 0xf; /* TODO */
>  awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
>  awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
> @@ -392,7 +392,7 @@ static void aspeed_1030_wdt_class_init(ObjectClass 
> *klass, void *data)
>  AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
>  
>  dc->desc = "ASPEED 1030 Watchdog Controller";
> -awc->offset = 0x80;
> +awc->iosize = 0x80;

Just noticed, the offset/iosize for the AST1030 seems to be incorrect. It
should be 0x40, not 0x80.

It should have the same value as the AST2600, since they should be the exact
same peripheral.

This is not your fault, just a bug report from me.

This seems to be an error in the original patch from Steven Lee, but also a bug 
in the AspeedSDK
Zephyr kernel driver?

e259e01ecb ("aspeed/wdt: Add AST1030 support")
https://github.com/AspeedTech-BMC/zephyr/blob/1b9764a854abbea8b38445f1d5de9f4441e29c3b/drivers/watchdog/wdt_aspeed.c#L21

The only

Re: [PATCH 6/9] hw/arm/aspeed_ast10x0: Map HACE peripheral

2022-12-30 Thread Peter Delevoryas
On Fri, Dec 30, 2022 at 09:13:29AM +0100, Philippe Mathieu-Daudé wrote:
> On 29/12/22 21:52, Peter Delevoryas wrote:
> > On Thu, Dec 29, 2022 at 04:23:22PM +0100, Philippe Mathieu-Daudé wrote:
> > > Since I don't have access to the datasheet, the relevant
> > > values were found in:
> > > https://github.com/AspeedTech-BMC/zephyr/blob/v00.01.08/dts/arm/aspeed/ast10x0.dtsi
> > > 
> > > Before on Zephyr:
> > > 
> > >uart:~$ crypto aes256_cbc_vault
> > >aes256_cbc vault key 1
> > >[00:00:06.699,000]  hace_global: aspeed_crypto_session_setup
> > >[00:00:06.699,000]  hace_global: data->cmd: 1c2098
> > >[00:00:06.699,000]  hace_global: crypto_data_src: 93340
> > >[00:00:06.699,000]  hace_global: crypto_data_dst: 93348
> > >[00:00:06.699,000]  hace_global: crypto_ctx_base: 93300
> > >[00:00:06.699,000]  hace_global: crypto_data_len: 8040
> > >[00:00:06.699,000]  hace_global: crypto_cmd_reg:  11c2098
> > >[00:00:09.743,000]  hace_global: HACE_STS: 0
> > >[00:00:09.743,000]  hace_global: HACE poll timeout
> > >[00:00:09.743,000]  crypto: CBC mode ENCRYPT - Failed
> > >[00:00:09.743,000]  hace_global: aspeed_crypto_session_free
> > >uart:~$
> > > 
> > > After:
> > > 
> > >uart:~$ crypto aes256_cbc_vault
> > >aes256_cbc vault key 1
> > >Was waiting for:
> > >6b c1 be e2 2e 40 9f 96 e9 3d 7e 11 73 93 17 2a
> > >ae 2d 8a 57 1e 03 ac 9c 9e b7 6f ac 45 af 8e 51
> > >30 c8 1c 46 a3 5c e4 11 e5 fb c1 19 1a 0a 52 ef
> > >f6 9f 24 45 df 4f 9b 17 ad 2b 41 7b e6 6c 37 10
> > > 
> > > But got:
> > >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > > 
> > >[00:00:05.771,000]  hace_global: aspeed_crypto_session_setup
> > >[00:00:05.772,000]  hace_global: data->cmd: 1c2098
> > >[00:00:05.772,000]  hace_global: crypto_data_src: 93340
> > >[00:00:05.772,000]  hace_global: crypto_data_dst: 93348
> > >[00:00:05.772,000]  hace_global: crypto_ctx_base: 93300
> > >[00:00:05.772,000]  hace_global: crypto_data_len: 8040
> > >[00:00:05.772,000]  hace_global: crypto_cmd_reg:  11c2098
> > >[00:00:05.772,000]  hace_global: HACE_STS: 1000
> > >[00:00:05.772,000]  crypto: Output length (encryption): 80
> > >[00:00:05.772,000]  hace_global: aspeed_crypto_session_free
> > >[00:00:05.772,000]  hace_global: aspeed_crypto_session_setup
> > >[00:00:05.772,000]  hace_global: data->cmd: 1c2018
> > >[00:00:05.772,000]  hace_global: crypto_data_src: 93340
> > >[00:00:05.772,000]  hace_global: crypto_data_dst: 93348
> > >[00:00:05.772,000]  hace_global: crypto_ctx_base: 93300
> > >[00:00:05.772,000]  hace_global: crypto_data_len: 8040
> > >[00:00:05.772,000]  hace_global: crypto_cmd_reg:  11c2018
> > >[00:00:05.772,000]  hace_global: HACE_STS: 1000
> > >[00:00:05.772,000]  crypto: Output length (decryption): 64
> > >[00:00:05.772,000]  crypto: CBC mode DECRYPT - Mismatch between 
> > > plaintext and decrypted cipher text
> > >[00:00:05.774,000]  hace_global: aspeed_crypto_session_free
> > >uart:~$
> > > 
> > > Signed-off-by: Philippe Mathieu-Daudé 
> > 
> > Awesome!
> > 
> > Reviewed-by: Peter Delevoryas 
> > 
> > > ---
> > > Should we rename HACE 'dram' as 'secram' / 'secure-ram'?
> > 
> > Sure, sounds good to me.
> > 
> > > ---
> > >   hw/arm/aspeed_ast10x0.c | 15 +++
> > >   1 file changed, 15 insertions(+)
> > > 
> > > diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> > > index 21a2e62345..02636705b6 100644
> > > --- a/hw/arm/aspeed_ast10x0.c
> > > +++ b/hw/arm/aspeed_ast10x0.c
> > > @@ -29,6 +29,7 @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
> > >   [ASPEED_DEV_SPI1]  = 0x7E63,
> > >   [ASPEED_DEV_SPI2]  = 0x7E64,
> > >   [ASPEED_DEV_UDC]   = 0x7E6A2000,
> > > +[ASPEED_DEV_HACE]  = 0x7E6D,
> > >   [ASPEED_DEV_SCU]   = 0x7E6E2000,
> > >   [ASPEED_DEV_JTAG0] = 0x7E6E4000,
> > >   [ASPEED_DEV_JTAG1] = 0x7E6E4100,
> &

Re: [PATCH v2 02/11] hw/watchdog/wdt_aspeed: Extend MMIO range to cover more registers

2022-12-30 Thread Peter Delevoryas
On Fri, Dec 30, 2022 at 01:31:35PM +0100, Philippe Mathieu-Daudé wrote:
> On 30/12/22 12:34, Philippe Mathieu-Daudé wrote:
> > When booting the Zephyr demo in [1] we get:
> > 
> >aspeed.io: unimplemented device write (size 4, offset 0x185128, value 
> > 0x030f1ff1) <--
> >aspeed.io: unimplemented device write (size 4, offset 0x18512c, value 
> > 0x03f1)
> > 
> > This corresponds to this Zephyr code [2]:
> > 
> >static int aspeed_wdt_init(const struct device *dev)
> >{
> >  const struct aspeed_wdt_config *config = dev->config;
> >  struct aspeed_wdt_data *const data = dev->data;
> >  uint32_t reg_val;
> > 
> >  /* disable WDT by default */
> >  reg_val = sys_read32(config->ctrl_base + WDT_CTRL_REG);
> >  reg_val &= ~WDT_CTRL_ENABLE;
> >  sys_write32(reg_val, config->ctrl_base + WDT_CTRL_REG);
> > 
> >  sys_write32(data->rst_mask1,
> >  config->ctrl_base + WDT_SW_RESET_MASK1_REG);   <--
> >  sys_write32(data->rst_mask2,
> >  config->ctrl_base + WDT_SW_RESET_MASK2_REG);
> > 
> >  return 0;
> >}
> > 
> > The register definitions are [3]:
> > 
> >#define WDT_RELOAD_VAL_REG  0x0004
> >#define WDT_RESTART_REG 0x0008
> >#define WDT_CTRL_REG0x000C
> >#define WDT_TIMEOUT_STATUS_REG  0x0010
> >#define WDT_TIMEOUT_STATUS_CLR_REG  0x0014
> >#define WDT_RESET_MASK1_REG 0x001C
> >#define WDT_RESET_MASK2_REG 0x0020
> >#define WDT_SW_RESET_MASK1_REG  0x0028   <--
> >#define WDT_SW_RESET_MASK2_REG  0x002C
> >#define WDT_SW_RESET_CTRL_REG   0x0024
> > 
> > Currently QEMU only cover a MMIO region of size 0x20:
> > 
> >#define ASPEED_WDT_REGS_MAX(0x20 / 4)
> > 
> > Change to map the whole 'iosize' which might be bigger, covering
> > the other registers. The MemoryRegionOps read/write handlers will
> > report the accesses as out-of-bounds guest-errors, but the next
> > commit will report them as unimplemented.

A I see, this makes perfect sense now, thanks for the detail!

> 
> I'll amend here for clarity:
> 
> ---
> 
> Memory layout before this change:
> 
>   (qemu) info mtree -f
> ...
> 7e785000-7e78501f (prio 0, i/o): aspeed.wdt
> 7e785020-7e78507f (prio -1000, i/o): aspeed.io
> @00185020
> 7e785080-7e78509f (prio 0, i/o): aspeed.wdt
> 7e7850a0-7e7850ff (prio -1000, i/o): aspeed.io
> @001850a0
> 7e785100-7e78511f (prio 0, i/o): aspeed.wdt
> 7e785120-7e78517f (prio -1000, i/o): aspeed.io
> @00185120
> 7e785180-7e78519f (prio 0, i/o): aspeed.wdt
> 7e7851a0-7e788fff (prio -1000, i/o): aspeed.io
> @001851a0
> 
> After:
> 
>   (qemu) info mtree -f
> ...
> 7e785000-7e78507f (prio 0, i/o): aspeed.wdt
> 7e785080-7e7850ff (prio 0, i/o): aspeed.wdt
> 7e785100-7e78517f (prio 0, i/o): aspeed.wdt
> 00007e785180-7e7851ff (prio 0, i/o): aspeed.wdt
> 7e785200-7e788fff (prio -1000, i/o): aspeed.io
> @00185200
> ---
> 
> > [1] https://github.com/AspeedTech-BMC/zephyr/releases/tag/v00.01.07
> > [2] https://github.com/AspeedTech-BMC/zephyr/commit/2e99f10ac27b
> > [3] 
> > https://github.com/AspeedTech-BMC/zephyr/blob/v00.01.08/drivers/watchdog/wdt_aspeed.c#L31
> > 
> > Reviewed-by: Peter Delevoryas 
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> >   hw/watchdog/wdt_aspeed.c | 3 ++-
> >   1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
> > index 958725a1b5..eefca31ae4 100644
> > --- a/hw/watchdog/wdt_aspeed.c
> > +++ b/hw/watchdog/wdt_aspeed.c
> > @@ -260,6 +260,7 @@ static void aspeed_wdt_realize(DeviceState *dev, Error 
> > **errp)
> >   {
> >   SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> >   AspeedWDTState *s = ASPEED_WDT(dev);
> > +AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(dev);
> >   assert(s->scu);
> > @@ -271,7 +272,7 @@ static void aspeed_wdt_realize(DeviceState *dev, Error 
> > **errp)
> >   s->pclk_freq = PCLK_HZ;
> >   memory_region_init_io(>iomem, OBJECT(s), _wdt_ops, s,
> > -  TYPE_ASPEED_WDT, ASPEED_WDT_REGS_MAX * 4);
> > +  TYPE_ASPEED_WDT, awc->iosize);
> >   sysbus_init_mmio(sbd, >iomem);
> >   }
> 



Re: [PATCH v2 03/11] hw/watchdog/wdt_aspeed: Log unimplemented registers as UNIMP level

2022-12-30 Thread Peter Delevoryas
On Fri, Dec 30, 2022 at 12:34:56PM +0100, Philippe Mathieu-Daudé wrote:
> Add more Aspeed watchdog registers from [*].
> 
> Since guests can righteously access them, log the access at
> 'unimplemented' level instead of 'guest-errors'.
> 
> [*] 
> https://github.com/AspeedTech-BMC/zephyr/blob/v00.01.08/drivers/watchdog/wdt_aspeed.c#L31
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Peter Delevoryas 

> ---
>  hw/watchdog/wdt_aspeed.c | 13 +
>  include/hw/watchdog/wdt_aspeed.h |  2 +-
>  2 files changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
> index eefca31ae4..d267aa185c 100644
> --- a/hw/watchdog/wdt_aspeed.c
> +++ b/hw/watchdog/wdt_aspeed.c
> @@ -42,6 +42,11 @@
>  #define WDT_PUSH_PULL_MAGIC (0xA8 << 24)
>  #define WDT_OPEN_DRAIN_MAGIC(0x8A << 24)
>  #define WDT_RESET_MASK1 (0x1c / 4)
> +#define WDT_RESET_MASK2 (0x20 / 4)
> +
> +#define WDT_SW_RESET_CTRL   (0x24 / 4)
> +#define WDT_SW_RESET_MASK1  (0x28 / 4)
> +#define WDT_SW_RESET_MASK2  (0x2c / 4)
>  
>  #define WDT_TIMEOUT_STATUS  (0x10 / 4)
>  #define WDT_TIMEOUT_CLEAR   (0x14 / 4)
> @@ -83,6 +88,10 @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr 
> offset, unsigned size)
>  return s->regs[WDT_RESET_MASK1];
>  case WDT_TIMEOUT_STATUS:
>  case WDT_TIMEOUT_CLEAR:
> +case WDT_RESET_MASK2:
> +case WDT_SW_RESET_CTRL:
> +case WDT_SW_RESET_MASK1:
> +case WDT_SW_RESET_MASK2:
>  qemu_log_mask(LOG_UNIMP,
>"%s: uninmplemented read at offset 0x%" HWADDR_PRIx 
> "\n",
>__func__, offset);
> @@ -190,6 +199,10 @@ static void aspeed_wdt_write(void *opaque, hwaddr 
> offset, uint64_t data,
>  
>  case WDT_TIMEOUT_STATUS:
>  case WDT_TIMEOUT_CLEAR:
> +case WDT_RESET_MASK2:
> +case WDT_SW_RESET_CTRL:
> +case WDT_SW_RESET_MASK1:
> +case WDT_SW_RESET_MASK2:
>  qemu_log_mask(LOG_UNIMP,
>"%s: uninmplemented write at offset 0x%" HWADDR_PRIx 
> "\n",
>__func__, offset);
> diff --git a/include/hw/watchdog/wdt_aspeed.h 
> b/include/hw/watchdog/wdt_aspeed.h
> index db91ee6b51..e90ef86651 100644
> --- a/include/hw/watchdog/wdt_aspeed.h
> +++ b/include/hw/watchdog/wdt_aspeed.h
> @@ -21,7 +21,7 @@ OBJECT_DECLARE_TYPE(AspeedWDTState, AspeedWDTClass, 
> ASPEED_WDT)
>  #define TYPE_ASPEED_2600_WDT TYPE_ASPEED_WDT "-ast2600"
>  #define TYPE_ASPEED_1030_WDT TYPE_ASPEED_WDT "-ast1030"
>  
> -#define ASPEED_WDT_REGS_MAX(0x20 / 4)
> +#define ASPEED_WDT_REGS_MAX(0x30 / 4)
>  
>  struct AspeedWDTState {
>  /*< private >*/
> -- 
> 2.38.1
> 



Re: [PATCH 7/9] hw/misc/aspeed_hace: Do not crash if address_space_map() failed

2022-12-29 Thread Peter Delevoryas
On Thu, Dec 29, 2022 at 04:23:23PM +0100, Philippe Mathieu-Daudé wrote:
> address_space_map() can fail:
> 
>   uart:~$ hash test
>   sha256_test
>   tv[0]:
>   Segmentation fault: 11
>   Thread 3 "qemu-system-arm" received signal SIGSEGV, Segmentation fault.
>   gen_acc_mode_iov (req_len=0x718b7778, id=, 
> iov=0x718b7780, s=0x56ce0bd0)
>   at ../hw/misc/aspeed_hace.c:171
>   171 if (has_padding(s, [id], *req_len, _msg_len, 
> _offset)) {
>   (gdb) bt
>   #0  gen_acc_mode_iov (req_len=0x718b7778, id=, 
> iov=0x718b7780, s=0x56ce0bd0)
>   at ../hw/misc/aspeed_hace.c:171
>   #1  do_hash_operation (s=s@entry=0x56ce0bd0, algo=3, 
> sg_mode=sg_mode@entry=true, acc_mode=acc_mode@entry=true)
>   at ../hw/misc/aspeed_hace.c:224
>   #2  0x559bdbb8 in aspeed_hace_write (opaque=, 
> addr=12, data=262488, size=)
>   at ../hw/misc/aspeed_hace.c:358
> 
> This change doesn't fix much, but at least the guest
> can't crash QEMU anymore. Instead it is still usable:
> 
>   uart:~$ hash test
>   sha256_test
>   tv[0]:hash_final error
>   sha384_test
>   tv[0]:hash_final error
>   sha512_test
>   tv[0]:hash_final error
>   [00:00:06.278,000]  hace_global: HACE poll timeout
>   [00:00:09.324,000]  hace_global: HACE poll timeout
>   [00:00:12.261,000]  hace_global: HACE poll timeout
>   uart:~$
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Good catch,

Reviewed-by: Peter Delevoryas 

Maybe include this tag?

Fixes: c5475b3f9a ("hw: Model ASPEED's Hash and Crypto Engine")

> ---
>  hw/misc/aspeed_hace.c | 21 +++--
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index ac21be306c..12a761f1f5 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -193,6 +193,7 @@ static void do_hash_operation(AspeedHACEState *s, int 
> algo, bool sg_mode,
>  size_t digest_len = 0;
>  int niov = 0;
>  int i;
> +void *haddr;
>  
>  if (sg_mode) {
>  uint32_t len = 0;
> @@ -217,9 +218,13 @@ static void do_hash_operation(AspeedHACEState *s, int 
> algo, bool sg_mode,
>  addr &= SG_LIST_ADDR_MASK;
>  
>  plen = len & SG_LIST_LEN_MASK;
> -iov[i].iov_base = address_space_map(>dram_as, addr, , 
> false,
> -MEMTXATTRS_UNSPECIFIED);
> -
> +haddr = address_space_map(>dram_as, addr, , false,
> +  MEMTXATTRS_UNSPECIFIED);
> +if (haddr == NULL) {
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", 
> __func__);
> +return;
> +}
> +iov[i].iov_base = haddr;
>  if (acc_mode) {
>  niov = gen_acc_mode_iov(s, iov, i, );
>  
> @@ -230,10 +235,14 @@ static void do_hash_operation(AspeedHACEState *s, int 
> algo, bool sg_mode,
>  } else {
>  hwaddr len = s->regs[R_HASH_SRC_LEN];
>  
> +haddr = address_space_map(>dram_as, s->regs[R_HASH_SRC],
> +  , false, MEMTXATTRS_UNSPECIFIED);
> +if (haddr == NULL) {
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
> +return;
> +}
> +iov[0].iov_base = haddr;
>  iov[0].iov_len = len;
> -iov[0].iov_base = address_space_map(>dram_as, s->regs[R_HASH_SRC],
> -, false,
> -MEMTXATTRS_UNSPECIFIED);
>  i = 1;
>  
>  if (s->iov_count) {
> -- 
> 2.38.1
> 



Re: [PATCH 8/9] hw/arm/aspeed_ast10x0: Add TODO comment to use Cortex-M4F

2022-12-29 Thread Peter Delevoryas
On Thu, Dec 29, 2022 at 04:23:24PM +0100, Philippe Mathieu-Daudé wrote:
> This SoC uses a Cortex-M4F. QEMU only implements a M4,
> which is good enough. Add a TODO note in case the M4F
> is added.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Oh, yeah good to have a note of this somewhere.

Reviewed-by: Peter Delevoryas 

> ---
>  hw/arm/aspeed_ast10x0.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index 02636705b6..788827ca9d 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -421,7 +421,7 @@ static void aspeed_soc_ast1030_class_init(ObjectClass 
> *klass, void *data)
>  dc->realize = aspeed_soc_ast1030_realize;
>  
>  sc->name = "ast1030-a1";
> -sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
> +sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-m4"); /* TODO cortex-m4f */
>  sc->silicon_rev = AST1030_A1_SILICON_REV;
>  sc->sram_size = 768 * KiB;
>  sc->secsram_size = 9 * KiB;
> -- 
> 2.38.1
> 



Re: [PATCH 9/9] tests/avocado: Test Aspeed Zephyr SDK v00.01.08 on AST1030 board

2022-12-29 Thread Peter Delevoryas
ot;
>   console: 0x510   0x1B  0x0| "
>   console: 0x510   0x1C  0x0| "
>   console: 0x510   0x1D  0x0| "
>   console: 0x510   0x1E  0x0| "
>   console: 0x510   0x1F  0x0\ "
>   console: 0x510   0x1E  0x0 Enable dedicate GPIO strap pins
>   console: 0x510   0x1F  0x0 Enable Secure Boot by Pin Strap
>   console: uart:~$ hwinfo devid
>   console: Length: 8
>   console: ID: 0x01800180
>   console: uart:~$ crypto aes256_cbc_vault
>   console: aes256_cbc vault key 1
>   console: Was waiting for:
>   console: 6b c1 be e2 2e 40 9f 96 e9 3d 7e 11 73 93 17 2a
>   console: ae 2d 8a 57 1e 03 ac 9c 9e b7 6f ac 45 af 8e 51
>   console: 30 c8 1c 46 a3 5c e4 11 e5 fb c1 19 1a 0a 52 ef
>   console: f6 9f 24 45 df 4f 9b 17 ad 2b 41 7b e6 6c 37 10
>   console: But got:
>   console: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   console: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   console: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   console: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   console: uart:~$ random get
>   console: 0x862460d
>   console: uart:~$ i2c scan I2C_0
>   console: 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
>   console: 00: -- -- -- -- -- -- -- -- -- -- -- --
>   console: 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>   console: 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>   console: 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>   console: 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>   console: 50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>   console: 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
>   console: 70: -- -- -- -- -- -- -- --
>   console: 1 devices found on I2C_0
>   console: uart:~$ kernel uptime
>   console: Uptime: 9897 ms
>   console: uart:~$ kernel reboot warm
>   console: *** Booting Zephyr OS build v00.01.07  ***
>   PASS (1.08 s)
> 
> Ref: 
> https://github.com/AspeedTech-BMC/zephyr/releases/download/v00.01.07/Aspeed_Zephy_SDK_User_Guide_v00.01.07.pdf
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Nice, very cool!

Reviewed-by: Peter Delevoryas 

> ---
>  tests/avocado/machine_aspeed.py | 41 -
>  1 file changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py
> index 1fc385e1c8..11f5b17eb9 100644
> --- a/tests/avocado/machine_aspeed.py
> +++ b/tests/avocado/machine_aspeed.py
> @@ -22,10 +22,11 @@ class AST1030Machine(QemuSystemTest):
>  
>  timeout = 10
>  
> -def test_ast1030_zephyros(self):
> +def test_ast1030_zephyros_1_04(self):
>  """
>  :avocado: tags=arch:arm
>  :avocado: tags=machine:ast1030-evb
> +:avocado: tags=os:zephyr
>  """
>  tar_url = ('https://github.com/AspeedTech-BMC'
> 
> '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip')
> @@ -41,6 +42,44 @@ def test_ast1030_zephyros(self):
>  exec_command_and_wait_for_pattern(self, "help",
>"Available commands")
>  
> +def test_ast1030_zephyros_1_07(self):
> +"""
> +:avocado: tags=arch:arm
> +:avocado: tags=machine:ast1030-evb
> +:avocado: tags=os:zephyr
> +"""
> +tar_url = ('https://github.com/AspeedTech-BMC'
> +   
> '/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip')
> +tar_hash = '40ac87eabdcd3b3454ce5aad11fedc72a33ecda2'
> +tar_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
> +archive.extract(tar_path, self.workdir)
> +kernel_file = self.workdir + "/ast1030-evb-demo/zephyr.bin"
> +self.vm.set_console()
> +self.vm.add_args('-kernel', kernel_file,
> + '-nographic')
> +self.vm.launch()
> +wait_for_console_pattern(self, "Booting Zephyr OS")
> +for shell_cmd in [
> +'kernel stacks',
> +'otp info conf',
> +'otp info scu',
> +'hwinfo devid',
> +'crypto aes256_cbc_vault',
> +'random get',
> +'jtag JTAG1 sw_xfer high TMS',
> +'adc ADC0 resolution 12',
> +'adc ADC0 read 42',
> +'adc ADC1 read 69',
> +'i2c scan I2C_0',
> +'i3c attach I3C_0',
> +'hash test',
> +'kernel uptime',
> +'kernel reboot warm',
> +'kernel uptime',
> +'kernel reboot cold',
> +'kernel uptime',
> +]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$")
> +
>  class AST2x00Machine(QemuSystemTest):
>  
>  timeout = 90
> -- 
> 2.38.1
> 



Re: [PATCH 6/9] hw/arm/aspeed_ast10x0: Map HACE peripheral

2022-12-29 Thread Peter Delevoryas
On Thu, Dec 29, 2022 at 04:23:22PM +0100, Philippe Mathieu-Daudé wrote:
> Since I don't have access to the datasheet, the relevant
> values were found in:
> https://github.com/AspeedTech-BMC/zephyr/blob/v00.01.08/dts/arm/aspeed/ast10x0.dtsi
> 
> Before on Zephyr:
> 
>   uart:~$ crypto aes256_cbc_vault
>   aes256_cbc vault key 1
>   [00:00:06.699,000]  hace_global: aspeed_crypto_session_setup
>   [00:00:06.699,000]  hace_global: data->cmd: 1c2098
>   [00:00:06.699,000]  hace_global: crypto_data_src: 93340
>   [00:00:06.699,000]  hace_global: crypto_data_dst: 93348
>   [00:00:06.699,000]  hace_global: crypto_ctx_base: 93300
>   [00:00:06.699,000]  hace_global: crypto_data_len: 8040
>   [00:00:06.699,000]  hace_global: crypto_cmd_reg:  11c2098
>   [00:00:09.743,000]  hace_global: HACE_STS: 0
>   [00:00:09.743,000]  hace_global: HACE poll timeout
>   [00:00:09.743,000]  crypto: CBC mode ENCRYPT - Failed
>   [00:00:09.743,000]  hace_global: aspeed_crypto_session_free
>   uart:~$
> 
> After:
> 
>   uart:~$ crypto aes256_cbc_vault
>   aes256_cbc vault key 1
>   Was waiting for:
>   6b c1 be e2 2e 40 9f 96 e9 3d 7e 11 73 93 17 2a
>   ae 2d 8a 57 1e 03 ac 9c 9e b7 6f ac 45 af 8e 51
>   30 c8 1c 46 a3 5c e4 11 e5 fb c1 19 1a 0a 52 ef
>   f6 9f 24 45 df 4f 9b 17 ad 2b 41 7b e6 6c 37 10
> 
>But got:
>   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 
>   [00:00:05.771,000]  hace_global: aspeed_crypto_session_setup
>   [00:00:05.772,000]  hace_global: data->cmd: 1c2098
>   [00:00:05.772,000]  hace_global: crypto_data_src: 93340
>   [00:00:05.772,000]  hace_global: crypto_data_dst: 93348
>   [00:00:05.772,000]  hace_global: crypto_ctx_base: 93300
>   [00:00:05.772,000]  hace_global: crypto_data_len: 8040
>   [00:00:05.772,000]  hace_global: crypto_cmd_reg:  11c2098
>   [00:00:05.772,000]  hace_global: HACE_STS: 1000
>   [00:00:05.772,000]  crypto: Output length (encryption): 80
>   [00:00:05.772,000]  hace_global: aspeed_crypto_session_free
>   [00:00:05.772,000]  hace_global: aspeed_crypto_session_setup
>   [00:00:05.772,000]  hace_global: data->cmd: 1c2018
>   [00:00:05.772,000]  hace_global: crypto_data_src: 93340
>   [00:00:05.772,000]  hace_global: crypto_data_dst: 93348
>   [00:00:05.772,000]  hace_global: crypto_ctx_base: 93300
>   [00:00:05.772,000]  hace_global: crypto_data_len: 8040
>   [00:00:05.772,000]  hace_global: crypto_cmd_reg:  11c2018
>   [00:00:05.772,000]  hace_global: HACE_STS: 1000
>   [00:00:05.772,000]  crypto: Output length (decryption): 64
>   [00:00:05.772,000]  crypto: CBC mode DECRYPT - Mismatch between 
> plaintext and decrypted cipher text
>   [00:00:05.774,000]  hace_global: aspeed_crypto_session_free
>   uart:~$
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Awesome!

Reviewed-by: Peter Delevoryas 

> ---
> Should we rename HACE 'dram' as 'secram' / 'secure-ram'?

Sure, sounds good to me.

> ---
>  hw/arm/aspeed_ast10x0.c | 15 +++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index 21a2e62345..02636705b6 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -29,6 +29,7 @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
>  [ASPEED_DEV_SPI1]  = 0x7E63,
>  [ASPEED_DEV_SPI2]  = 0x7E64,
>  [ASPEED_DEV_UDC]   = 0x7E6A2000,
> +[ASPEED_DEV_HACE]  = 0x7E6D,
>  [ASPEED_DEV_SCU]   = 0x7E6E2000,
>  [ASPEED_DEV_JTAG0] = 0x7E6E4000,
>  [ASPEED_DEV_JTAG1] = 0x7E6E4100,
> @@ -166,6 +167,9 @@ static void aspeed_soc_ast1030_init(Object *obj)
>  snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
>  object_initialize_child(obj, "gpio", >gpio, typename);
>  
> +snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
> +object_initialize_child(obj, "hace", >hace, typename);
> +
>  object_initialize_child(obj, "iomem", >iomem, 
> TYPE_UNIMPLEMENTED_DEVICE);
>  object_initialize_child(obj, "sbc-unimplemented", >sbc_unimplemented,
>  TYPE_UNIMPLEMENTED_DEVICE);
> @@ -359,6 +363,17 @@ static void aspeed_soc_ast1030_realize(DeviceState 
> *dev_soc, Error **errp)
>  }
>  aspeed_mmio_map(s, SYS_BUS_DEVICE(>sbc), 0, 
> sc->memmap[ASPEED_DEV_SBC]);
>  
> +/* HACE */
> +object_property_set_link(OBJECT(>hace), "dram", OBJECT(>secsram),
> + _abort);
> +   

Re: [PATCH 5/9] hw/arm/aspeed_ast10x0: Map the secure SRAM

2022-12-29 Thread Peter Delevoryas
On Thu, Dec 29, 2022 at 04:23:21PM +0100, Philippe Mathieu-Daudé wrote:
> Some SRAM appears to be used by the Secure Boot unit and
> crypto accelerators. Name it 'secure sram'.
> 
> Note, the SRAM base address was already present but unused
> (the 'SBC' index is used for the MMIO peripheral).
> 
> Interestingly using CFLAGS=-Winitializer-overrides reports:
> 
>   ../hw/arm/aspeed_ast10x0.c:32:30: warning: initializer overrides prior 
> initialization of this subobject [-Winitializer-overrides]
> [ASPEED_DEV_SBC]   = 0x7E6F2000,
>  ^~
>   ../hw/arm/aspeed_ast10x0.c:24:30: note: previous initialization is here
> [ASPEED_DEV_SBC]   = 0x7900,
>  ^~

O! Oh no, yeah I think Zephyr has this warning enabled by default, right? I
guess it's not enabled in QEMU? H.

Reviewed-by: Peter Delevoryas 

Also maybe include this tag?

Fixes: 356b230ed1 ("aspeed/soc : Add AST1030 support")

> This fixes with Zephyr:
> 
>   uart:~$ rsa test
>   rsa test vector[0]:
>   [00:00:26.156,000]  os: * BUS FAULT *
>   [00:00:26.157,000]  os:   Precise data bus error
>   [00:00:26.157,000]  os:   BFAR Address: 0x7900
>   [00:00:26.158,000]  os: r0/a1:  0x7900  r1/a2:  0x  r2/a3: 
>  0x1800
>   [00:00:26.158,000]  os: r3/a4:  0x79001800 r12/ip:  0x0800 r14/lr: 
>  0x0001098d
>   [00:00:26.158,000]  os:  xpsr:  0x8100
>   [00:00:26.158,000]  os: Faulting instruction address (r15/pc): 
> 0x0001e1bc
>   [00:00:26.158,000]  os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU > 0
>   [00:00:26.158,000]  os: Current thread: 0x38248 (shell_uart)
>   [00:00:26.165,000]  os: Halting system
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/arm/aspeed_ast10x0.c | 11 ++-
>  include/hw/arm/aspeed_soc.h |  3 +++
>  2 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index 53ea6d471f..21a2e62345 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -22,7 +22,7 @@
>  
>  static const hwaddr aspeed_soc_ast1030_memmap[] = {
>  [ASPEED_DEV_SRAM]  = 0x,
> -[ASPEED_DEV_SBC]   = 0x7900,
> +[ASPEED_DEV_SECSRAM]   = 0x7900,
>  [ASPEED_DEV_IOMEM] = 0x7E60,
>  [ASPEED_DEV_PWM]   = 0x7E61,
>  [ASPEED_DEV_FMC]   = 0x7E62,
> @@ -222,6 +222,14 @@ static void aspeed_soc_ast1030_realize(DeviceState 
> *dev_soc, Error **errp)
>  memory_region_add_subregion(s->memory,
>  sc->memmap[ASPEED_DEV_SRAM],
>  >sram);
> +memory_region_init_ram(>secsram, OBJECT(s), "sec.sram",
> +   sc->secsram_size, );
> +if (err != NULL) {
> +error_propagate(errp, err);
> +return;
> +}
> +memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SECSRAM],
> +>secsram);
>  
>  /* SCU */
>  if (!sysbus_realize(SYS_BUS_DEVICE(>scu), errp)) {
> @@ -401,6 +409,7 @@ static void aspeed_soc_ast1030_class_init(ObjectClass 
> *klass, void *data)
>  sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
>  sc->silicon_rev = AST1030_A1_SILICON_REV;
>  sc->sram_size = 768 * KiB;
> +sc->secsram_size = 9 * KiB;
>  sc->spis_num = 2;
>  sc->ehcis_num = 0;
>  sc->wdts_num = 4;
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index 9a5e3c0bac..bd1e03e78a 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -71,6 +71,7 @@ struct AspeedSoCState {
>  AspeedSMCState spi[ASPEED_SPIS_NUM];
>  EHCISysBusState ehci[ASPEED_EHCIS_NUM];
>  AspeedSBCState sbc;
> +MemoryRegion secsram;
>  UnimplementedDeviceState sbc_unimplemented;
>  AspeedSDMCState sdmc;
>  AspeedWDTState wdt[ASPEED_WDTS_NUM];
> @@ -105,6 +106,7 @@ struct AspeedSoCClass {
>  const char *cpu_type;
>  uint32_t silicon_rev;
>  uint64_t sram_size;
> +uint64_t secsram_size;
>  int spis_num;
>  int ehcis_num;
>  int wdts_num;
> @@ -143,6 +145,7 @@ enum {
>  ASPEED_DEV_SCU,
>  ASPEED_DEV_ADC,
>  ASPEED_DEV_SBC,
> +ASPEED_DEV_SECSRAM,
>  ASPEED_DEV_EMMC_BC,
>  ASPEED_DEV_VIDEO,
>  ASPEED_DEV_SRAM,
> -- 
> 2.38.1
> 



Re: [PATCH 4/9] hw/arm/aspeed_ast10x0: Map I3C peripheral

2022-12-29 Thread Peter Delevoryas
On Thu, Dec 29, 2022 at 04:23:20PM +0100, Philippe Mathieu-Daudé wrote:
> Since I don't have access to the datasheet, the relevant
> values were found in:
> https://github.com/AspeedTech-BMC/zephyr/blob/v00.01.08/dts/arm/aspeed/ast10x0.dtsi
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/arm/aspeed_ast10x0.c | 16 
>  1 file changed, 16 insertions(+)
> 
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index d7dbc1a801..53ea6d471f 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -54,6 +54,7 @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
>  [ASPEED_DEV_WDT]   = 0x7E785000,
>  [ASPEED_DEV_LPC]   = 0x7E789000,
>  [ASPEED_DEV_PECI]  = 0x7E78B000,
> +[ASPEED_DEV_I3C]   = 0x7E7A,
>  [ASPEED_DEV_I2C]   = 0x7E7B,
>  };
>  
> @@ -89,6 +90,7 @@ static const int aspeed_soc_ast1030_irqmap[] = {
>  [ASPEED_DEV_ADC]   = 46,
>  [ASPEED_DEV_SPI1]  = 65,
>  [ASPEED_DEV_SPI2]  = 66,
> +[ASPEED_DEV_I3C]   = 102, /* 102 -> 105 */
>  [ASPEED_DEV_I2C]   = 110, /* 110 ~ 123 */
>  [ASPEED_DEV_KCS]   = 138, /* 138 -> 142 */
>  [ASPEED_DEV_UDC]   = 9,
> @@ -130,6 +132,8 @@ static void aspeed_soc_ast1030_init(Object *obj)
>  snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
>  object_initialize_child(obj, "i2c", >i2c, typename);
>  
> +object_initialize_child(obj, "i3c", >i3c, TYPE_ASPEED_I3C);
> +
>  snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
>  object_initialize_child(obj, "timerctrl", >timerctrl, typename);
>  
> @@ -240,6 +244,18 @@ static void aspeed_soc_ast1030_realize(DeviceState 
> *dev_soc, Error **errp)
>  sysbus_connect_irq(SYS_BUS_DEVICE(>i2c.busses[i]), 0, irq);
>  }
>  
> +/* I3C */
> +if (!sysbus_realize(SYS_BUS_DEVICE(>i3c), errp)) {
> +return;
> +}
> +aspeed_mmio_map(s, SYS_BUS_DEVICE(>i3c), 0, 
> sc->memmap[ASPEED_DEV_I3C]);
> +for (i = 0; i < ASPEED_I3C_NR_DEVICES; i++) {
> +qemu_irq irq = qdev_get_gpio_in(DEVICE(>armv7m),
> +sc->irqmap[ASPEED_DEV_I3C] + i);
> +/* The AST1030 I2C controller has one IRQ per bus. */

Should this comment be I2C or I3C?

Otherwise looks good!

Reviewed-by: Peter Delevoryas 

> +sysbus_connect_irq(SYS_BUS_DEVICE(>i3c.devices[i]), 0, irq);
> +}
> +
>  /* PECI */
>  if (!sysbus_realize(SYS_BUS_DEVICE(>peci), errp)) {
>  return;
> -- 
> 2.38.1
k 



Re: [PATCH 3/9] hw/arm/aspeed_ast10x0: Add various unimplemented peripherals

2022-12-29 Thread Peter Delevoryas
:n Thu, Dec 29, 2022 at 04:23:19PM +0100, Philippe Mathieu-Daudé wrote:
> Based on booting Zephyr demo from [1] running QEMU with
> '-d unimp' and checking missing devices in [2].
> 
> [1] https://github.com/AspeedTech-BMC/zephyr/releases/tag/v00.01.07
> [2] 
> https://github.com/AspeedTech-BMC/zephyr/blob/v00.01.08/dts/arm/aspeed/ast10x0.dtsi
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Oh cool, yeah looks good.

Reviewed-by: Peter Delevoryas 

> ---
>  hw/arm/aspeed_ast10x0.c | 35 +++
>  include/hw/arm/aspeed_soc.h | 11 +++
>  2 files changed, 46 insertions(+)
> 
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index 3500294df7..d7dbc1a801 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -28,10 +28,15 @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
>  [ASPEED_DEV_FMC]   = 0x7E62,
>  [ASPEED_DEV_SPI1]  = 0x7E63,
>  [ASPEED_DEV_SPI2]  = 0x7E64,
> +[ASPEED_DEV_UDC]   = 0x7E6A2000,
>  [ASPEED_DEV_SCU]   = 0x7E6E2000,
> +[ASPEED_DEV_JTAG0] = 0x7E6E4000,
> +[ASPEED_DEV_JTAG1] = 0x7E6E4100,
>  [ASPEED_DEV_ADC]   = 0x7E6E9000,
> +[ASPEED_DEV_ESPI]  = 0x7E6EE000,
>  [ASPEED_DEV_SBC]   = 0x7E6F2000,
>  [ASPEED_DEV_GPIO]  = 0x7E78,
> +[ASPEED_DEV_SGPIOM]= 0x7E780500,
>  [ASPEED_DEV_TIMER1]= 0x7E782000,
>  [ASPEED_DEV_UART1] = 0x7E783000,
>  [ASPEED_DEV_UART2] = 0x7E78D000,
> @@ -79,12 +84,17 @@ static const int aspeed_soc_ast1030_irqmap[] = {
>  [ASPEED_DEV_LPC]   = 35,
>  [ASPEED_DEV_PECI]  = 38,
>  [ASPEED_DEV_FMC]   = 39,
> +[ASPEED_DEV_ESPI]  = 42,
>  [ASPEED_DEV_PWM]   = 44,
>  [ASPEED_DEV_ADC]   = 46,
>  [ASPEED_DEV_SPI1]  = 65,
>  [ASPEED_DEV_SPI2]  = 66,
>  [ASPEED_DEV_I2C]   = 110, /* 110 ~ 123 */
>  [ASPEED_DEV_KCS]   = 138, /* 138 -> 142 */
> +[ASPEED_DEV_UDC]   = 9,
> +[ASPEED_DEV_SGPIOM]= 51,
> +[ASPEED_DEV_JTAG0] = 27,
> +[ASPEED_DEV_JTAG1] = 53,
>  };
>  
>  static qemu_irq aspeed_soc_ast1030_get_irq(AspeedSoCState *s, int dev)
> @@ -155,6 +165,15 @@ static void aspeed_soc_ast1030_init(Object *obj)
>  object_initialize_child(obj, "iomem", >iomem, 
> TYPE_UNIMPLEMENTED_DEVICE);
>  object_initialize_child(obj, "sbc-unimplemented", >sbc_unimplemented,
>  TYPE_UNIMPLEMENTED_DEVICE);
> +object_initialize_child(obj, "pwm", >pwm, TYPE_UNIMPLEMENTED_DEVICE);
> +object_initialize_child(obj, "espi", >espi, 
> TYPE_UNIMPLEMENTED_DEVICE);
> +object_initialize_child(obj, "udc", >udc, TYPE_UNIMPLEMENTED_DEVICE);
> +object_initialize_child(obj, "sgpiom", >sgpiom,
> +TYPE_UNIMPLEMENTED_DEVICE);
> +object_initialize_child(obj, "jtag[0]", >jtag[0],
> +TYPE_UNIMPLEMENTED_DEVICE);
> +object_initialize_child(obj, "jtag[1]", >jtag[1],
> +TYPE_UNIMPLEMENTED_DEVICE);
>  }
>  
>  static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
> @@ -337,6 +356,22 @@ static void aspeed_soc_ast1030_realize(DeviceState 
> *dev_soc, Error **errp)
>  sc->memmap[ASPEED_DEV_GPIO]);
>  sysbus_connect_irq(SYS_BUS_DEVICE(>gpio), 0,
> aspeed_soc_get_irq(s, ASPEED_DEV_GPIO));
> +
> +aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(>pwm), "aspeed.pwm",
> +  sc->memmap[ASPEED_DEV_PWM], 0x100);
> +
> +aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(>espi), "aspeed.espi",
> +  sc->memmap[ASPEED_DEV_ESPI], 0x800);
> +
> +aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(>udc), "aspeed.udc",
> +  sc->memmap[ASPEED_DEV_UDC], 0x1000);
> +aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(>sgpiom), 
> "aspeed.sgpiom",
> +  sc->memmap[ASPEED_DEV_SGPIOM], 0x100);
> +
> +aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(>jtag[0]), 
> "aspeed.jtag",
> +  sc->memmap[ASPEED_DEV_JTAG0], 0x20);
> +aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(>jtag[1]), 
> "aspeed.jtag",
> +  sc->memmap[ASPEED_DEV_JTAG1], 0x20);
>  }
>  
>  static void aspeed_soc_ast1030_class_init(ObjectClass *klass, void *data)
> diff --git a

Re: [PATCH 2/9] hw/arm/aspeed: Use the IEC binary prefix definitions

2022-12-29 Thread Peter Delevoryas
On Thu, Dec 29, 2022 at 04:23:18PM +0100, Philippe Mathieu-Daudé wrote:
> IEC binary prefixes ease code review: the unit is explicit.

Oh, yeah, another good idea.

Reviewed-by: Peter Delevoryas 

> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/arm/aspeed_ast10x0.c | 3 ++-
>  hw/arm/aspeed_ast2600.c | 3 ++-
>  hw/arm/aspeed_soc.c | 4 ++--
>  3 files changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index 122b3fd3f3..3500294df7 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -10,6 +10,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/units.h"
>  #include "qapi/error.h"
>  #include "exec/address-spaces.h"
>  #include "sysemu/sysemu.h"
> @@ -348,7 +349,7 @@ static void aspeed_soc_ast1030_class_init(ObjectClass 
> *klass, void *data)
>  sc->name = "ast1030-a1";
>  sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
>  sc->silicon_rev = AST1030_A1_SILICON_REV;
> -sc->sram_size = 0xc;
> +sc->sram_size = 768 * KiB;
>  sc->spis_num = 2;
>  sc->ehcis_num = 0;
>  sc->wdts_num = 4;
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index a79e05ddbd..72df72a540 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -8,6 +8,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/units.h"
>  #include "qapi/error.h"
>  #include "hw/misc/unimp.h"
>  #include "hw/arm/aspeed_soc.h"
> @@ -619,7 +620,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass 
> *oc, void *data)
>  sc->name = "ast2600-a3";
>  sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
>  sc->silicon_rev  = AST2600_A3_SILICON_REV;
> -sc->sram_size= 0x16400;
> +sc->sram_size= 89 * KiB;
>  sc->spis_num = 2;
>  sc->ehcis_num= 2;
>  sc->wdts_num = 4;
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 2c0924d311..677342c9ed 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -517,7 +517,7 @@ static void aspeed_soc_ast2400_class_init(ObjectClass 
> *oc, void *data)
>  sc->name = "ast2400-a1";
>  sc->cpu_type = ARM_CPU_TYPE_NAME("arm926");
>  sc->silicon_rev  = AST2400_A1_SILICON_REV;
> -sc->sram_size= 0x8000;
> +sc->sram_size= 32 * KiB;
>  sc->spis_num = 1;
>  sc->ehcis_num= 1;
>  sc->wdts_num = 2;
> @@ -544,7 +544,7 @@ static void aspeed_soc_ast2500_class_init(ObjectClass 
> *oc, void *data)
>  sc->name = "ast2500-a1";
>  sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176");
>  sc->silicon_rev  = AST2500_A1_SILICON_REV;
> -sc->sram_size= 0x9000;
> +sc->sram_size= 36 * KiB;
>  sc->spis_num = 2;
>  sc->ehcis_num= 2;
>  sc->wdts_num = 3;
> -- 
> 2.38.1
> 



Re: [PATCH 1/9] hw/watchdog/wdt_aspeed: Map the whole MMIO range

2022-12-29 Thread Peter Delevoryas
c->offset = 0x20;
> +awc->iosize = 0x20;
>  awc->ext_pulse_width_mask = 0xf;
>  awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
>  awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
> @@ -369,7 +371,7 @@ static void aspeed_2600_wdt_class_init(ObjectClass 
> *klass, void *data)
>  AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
>  
>  dc->desc = "ASPEED 2600 Watchdog Controller";
> -awc->offset = 0x40;
> +awc->iosize = 0x40;
>  awc->ext_pulse_width_mask = 0xf; /* TODO */
>  awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
>  awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
> @@ -392,7 +394,7 @@ static void aspeed_1030_wdt_class_init(ObjectClass 
> *klass, void *data)
>  AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
>  
>  dc->desc = "ASPEED 1030 Watchdog Controller";
> -awc->offset = 0x80;
> +awc->iosize = 0x80;
>  awc->ext_pulse_width_mask = 0xf; /* TODO */
>  awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
>  awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
> diff --git a/include/hw/watchdog/wdt_aspeed.h 
> b/include/hw/watchdog/wdt_aspeed.h
> index dfa5dfa424..db91ee6b51 100644
> --- a/include/hw/watchdog/wdt_aspeed.h
> +++ b/include/hw/watchdog/wdt_aspeed.h
> @@ -40,7 +40,7 @@ struct AspeedWDTState {
>  struct AspeedWDTClass {
>  SysBusDeviceClass parent_class;
>  
> -uint32_t offset;
> +uint32_t iosize;

Oh yeah, iosize is a way better name for this. +1. But to be honest, I don't
understand how this is changing the unimplemented traces?

Reviewed-by: Peter Delevoryas 

>  uint32_t ext_pulse_width_mask;
>  uint32_t reset_ctrl_reg;
>  void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
> -- 
> 2.38.1
> 



Re: [PATCH 0/9] hw/arm/aspeed_ast10x0: Map more peripherals & few more fixes

2022-12-29 Thread Peter Delevoryas
On Thu, Dec 29, 2022 at 04:23:16PM +0100, Philippe Mathieu-Daudé wrote:
> Trying to fix some bugs triggered running Zephyr.

Yay!

> 
> Still 2 bugs:
> 
> 1/
> uart:~$ sensor get SYSCLK
> [00:00:23.592,000]  os: * USAGE FAULT *
> [00:00:23.593,000]  os:   Illegal use of the EPSR
> [00:00:23.593,000]  os: r0/a1:  0x00033448  r1/a2:  0x  r2/a3:  
> 0x00047f50
> [00:00:23.593,000]  os: r3/a4:  0x r12/ip:  0x r14/lr:  
> 0x0fbd
> [00:00:23.593,000]  os:  xpsr:  0x6000
> [00:00:23.593,000]  os: Faulting instruction address (r15/pc): 0x
> [00:00:23.593,000]  os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
> [00:00:23.594,000]  os: Current thread: 0x38248 (shell_uart)
> [00:00:23.601,000]  os: Halting system
> 
> 2/
> uart:~$ mcuboot
> [00:01:04.990,000]  os: * BUS FAULT *
> [00:01:04.990,000]  os:   Instruction bus error
> [00:01:04.991,000]  os: r0/a1:  0x  r1/a2:  0x0000  r2/a3:  
> 0x00047ef0
> [00:01:04.991,000]  os: r3/a4:  0x0010 r12/ip:  0x6df7ecb5 r14/lr:  
> 0x000188ed
> [00:01:04.991,000]  os:  xpsr:  0x6100
> [00:01:04.991,000]  os: Faulting instruction address (r15/pc): 0x6df7ecb4
> [00:01:04.991,000]  os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
> [00:01:04.991,000]  os: Current thread: 0x38248 (shell_uart)
> [00:01:04.994,000]  os: Halting system
> 
> 
> IN:
> PMSA MPU lookup for reading at 0x0001d400 mmu_idx 65 -> Hit (prot rwx)
> 0x0001d5a2:  6869   ldr  r1, [r5, #4]
> 0x0001d5a4:  4421   add  r1, r4
> 0x0001d5a6:  6883   ldr  r3, [r0, #8]
> 0x0001d5a8:  681c   ldr  r4, [r3]
> 0x0001d5aa:  463a   mov  r2, r7
> 0x0001d5ac:  4633   mov  r3, r6
> 0x0001d5ae:  46a4   mov  ip, r4
> 0x0001d5b0:  e8bd 41f0  pop.w{r4, r5, r6, r7, r8, lr}
> 0x0001d5b4:  4760   bx   ip
> 
> PMSA MPU lookup for reading at 0x0008 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for execute at 0x6df7ecb4 mmu_idx 65 -> Hit (prot rwx)
> Taking exception 3 [Prefetch Abort] on CPU 0
> ...at fault address 0x6df7ecb4
> ...with CFSR.IBUSERR
> PMSA MPU lookup for writing at 0x00047ec8 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x00047ecc mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x00047ed0 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x00047ed4 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x00047ed8 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x00047edc mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x00047ee0 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x00047ee4 mmu_idx 65 -> Hit (prot rwx)
> ...taking pending nonsecure exception 5
> ...loading from element 5 of non-secure vector table at 0x14
> ...loaded new PC 0xa0cd
> 
> 
> HACE isn't really functional there. I probably screwed smth while wiring
> the peripheral. Not obvious without access to the datasheet.

Hm well I have the datasheet, but I don't see what the issue could be. The
MMIO address for the HACE is correct (0x7E6D_), what else could be wrong?

> 
> Philippe Mathieu-Daudé (9):
>   hw/watchdog/wdt_aspeed: Map the whole MMIO range
>   hw/arm/aspeed: Use the IEC binary prefix definitions
>   hw/arm/aspeed_ast10x0: Add various unimplemented peripherals
>   hw/arm/aspeed_ast10x0: Map I3C peripheral
>   hw/arm/aspeed_ast10x0: Map the secure SRAM
>   hw/arm/aspeed_ast10x0: Map HACE peripheral
>   hw/misc/aspeed_hace: Do not crash if address_space_map() failed
>   hw/arm/aspeed_ast10x0: Add TODO comment to use Cortex-M4F
>   tests/avocado: Test Aspeed Zephyr SDK v00.01.08 on AST1030 board
> 
>  hw/arm/aspeed_ast10x0.c  | 84 ++--
>  hw/arm/aspeed_ast2600.c  |  5 +-
>  hw/arm/aspeed_soc.c  |  6 +--
>  hw/misc/aspeed_hace.c| 21 +---
>  hw/watchdog/wdt_aspeed.c | 12 +++--
>  include/hw/arm/aspeed_soc.h  | 14 ++
>  include/hw/watchdog/wdt_aspeed.h |  2 +-
>  tests/avocado/machine_aspeed.py  | 41 +++-
>  8 files changed, 163 insertions(+), 22 deletions(-)
> 
> -- 
> 2.38.1
> 



Re: [PATCH 08/11] contrib/gitdm: Add Facebook the domain map

2022-12-19 Thread Peter Delevoryas


> On Dec 19, 2022, at 7:49 AM, Philippe Mathieu-Daudé  wrote:
> 
> !---|
> This Message Is From an External Sender
> 
> |---!
> 
> On 19/12/22 16:22, Peter Delevoryas wrote:
>>> On Dec 19, 2022, at 4:19 AM, Alex Bennée  wrote:
>>> 
>>> !---|
>>>  This Message Is From an External Sender
>>> 
>>> |---!
>>> 
>>> A number of Facebook developers contribute to the project. Peter can
>>> you confirm your want pjd.dev contributions counted here or as
>>> an individual contributor?
>> Oh, hey: yes I can confirm that, I want pjd.dev contributions counted here 
>> as fb stuff.
>> By the way: recently, every Facebook developers email has migrated to 
>> “usern...@meta.com”. So now all my fb.com email goes to my meta.com inbox. 
>> We may or may not want to include both emails. I think the fb.com emails 
>> will stay around for quite a while, but yeah.
> 
> gitdm tool is only use to display statistics from your past
> contributions. If you want the get_maintainers.pl script to
> use your updated email address, you probably want to send a
> patch to update the .mailmap file.

Ok: at this point, I just use pe...@pjd.dev <mailto:pe...@pjd.dev> because the 
email filters at Facebook are so onerous and drop things mysteriously all the 
time, so I’ll probably just keep using that I guess. But maybe I’ll try 
submitting a single patch as p...@meta.com <mailto:p...@meta.com> sometime.

Thanks!
Peter

> 
>>> Signed-off-by: Alex Bennée 
>>> Cc: Iris Chen 
>>> Cc: Peter Delevoryas 
>>> Cc: Peter Delevoryas 
>>> Cc: Daniel Müller 
>>> ---
>>> contrib/gitdm/domain-map | 1 +
>>> contrib/gitdm/group-map-facebook | 5 +
>>> gitdm.config | 1 +
>>> 3 files changed, 7 insertions(+)
>>> create mode 100644 contrib/gitdm/group-map-facebook



Re: [PATCH 08/11] contrib/gitdm: Add Facebook the domain map

2022-12-19 Thread Peter Delevoryas


> On Dec 19, 2022, at 7:56 AM, Peter Delevoryas  wrote:
> 
> 
> 
>> On Dec 19, 2022, at 7:49 AM, Philippe Mathieu-Daudé  
>> wrote:
>> 
>> !---|
>> This Message Is From an External Sender
>> 
>> |-------!
>> 
>> On 19/12/22 16:22, Peter Delevoryas wrote:
>>>> On Dec 19, 2022, at 4:19 AM, Alex Bennée  wrote:
>>>> 
>>>> !---|
>>>> This Message Is From an External Sender
>>>> 
>>>> |---!
>>>> 
>>>> A number of Facebook developers contribute to the project. Peter can
>>>> you confirm your want pjd.dev contributions counted here or as
>>>> an individual contributor?
>>> Oh, hey: yes I can confirm that, I want pjd.dev contributions counted here 
>>> as fb stuff.
>>> By the way: recently, every Facebook developers email has migrated to 
>>> “usern...@meta.com”. So now all my fb.com email goes to my meta.com inbox. 
>>> We may or may not want to include both emails. I think the fb.com emails 
>>> will stay around for quite a while, but yeah.
>> 
>> gitdm tool is only use to display statistics from your past
>> contributions. If you want the get_maintainers.pl script to
>> use your updated email address, you probably want to send a
>> patch to update the .mailmap file.
> 
> Ok: at this point, I just use pe...@pjd.dev <mailto:pe...@pjd.dev> because 
> the email filters at Facebook are so onerous and drop things mysteriously all 
> the time, so I’ll probably just keep using that I guess. But maybe I’ll try 
> submitting a single patch as p...@meta.com <mailto:p...@meta.com> sometime.

Oh, almost forgot:

Reviewed-by: Peter Delevoryas mailto:pe...@pjd.dev>>

> 
> Thanks!
> Peter
> 
>> 
>>>> Signed-off-by: Alex Bennée 
>>>> Cc: Iris Chen 
>>>> Cc: Peter Delevoryas 
>>>> Cc: Peter Delevoryas 
>>>> Cc: Daniel Müller 
>>>> ---
>>>> contrib/gitdm/domain-map | 1 +
>>>> contrib/gitdm/group-map-facebook | 5 +
>>>> gitdm.config | 1 +
>>>> 3 files changed, 7 insertions(+)
>>>> create mode 100644 contrib/gitdm/group-map-facebook




Re: [PATCH 08/11] contrib/gitdm: Add Facebook the domain map

2022-12-19 Thread Peter Delevoryas



> On Dec 19, 2022, at 4:19 AM, Alex Bennée  wrote:
> 
> !---|
>  This Message Is From an External Sender
> 
> |---!
> 
> A number of Facebook developers contribute to the project. Peter can
> you confirm your want pjd.dev contributions counted here or as
> an individual contributor?

Oh, hey: yes I can confirm that, I want pjd.dev contributions counted here as 
fb stuff.

By the way: recently, every Facebook developers email has migrated to 
“usern...@meta.com”. So now all my fb.com email goes to my meta.com inbox. We 
may or may not want to include both emails. I think the fb.com emails will stay 
around for quite a while, but yeah.

> 
> Signed-off-by: Alex Bennée 
> Cc: Iris Chen 
> Cc: Peter Delevoryas 
> Cc: Peter Delevoryas 
> Cc: Daniel Müller 
> ---
> contrib/gitdm/domain-map | 1 +
> contrib/gitdm/group-map-facebook | 5 +
> gitdm.config | 1 +
> 3 files changed, 7 insertions(+)
> create mode 100644 contrib/gitdm/group-map-facebook
> 
> diff --git a/contrib/gitdm/domain-map b/contrib/gitdm/domain-map
> index 03d12b3ba6..22d7f953e1 100644
> --- a/contrib/gitdm/domain-map
> +++ b/contrib/gitdm/domain-map
> @@ -14,6 +14,7 @@ citrix.com  Citrix
> crudebyte.com   Crudebyte
> chinatelecom.cn China Telecom
> eldorado.org.br Instituto de Pesquisas Eldorado
> +fb.com  Facebook
> fujitsu.com Fujitsu
> google.com  Google
> greensocs.com   GreenSocs
> diff --git a/contrib/gitdm/group-map-facebook 
> b/contrib/gitdm/group-map-facebook
> new file mode 100644
> index 00..38589f8fb9
> --- /dev/null
> +++ b/contrib/gitdm/group-map-facebook
> @@ -0,0 +1,5 @@
> +#
> +# Some Facebook contributors also occasionally use personal email addresses.
> +#
> +
> +pe...@pjd.dev
> diff --git a/gitdm.config b/gitdm.config
> index f79d39df63..75b55b3603 100644
> --- a/gitdm.config
> +++ b/gitdm.config
> @@ -33,6 +33,7 @@ EmailMap contrib/gitdm/domain-map
> 
> GroupMap contrib/gitdm/group-map-cadence Cadence Design Systems
> GroupMap contrib/gitdm/group-map-codeweavers CodeWeavers
> +GroupMap contrib/gitdm/group-map-facebook Facebook
> GroupMap contrib/gitdm/group-map-ibm IBM
> GroupMap contrib/gitdm/group-map-janustech Janus Technologies
> GroupMap contrib/gitdm/group-map-netflix Netflix
> -- 
> 2.34.1
> 




Re: [PATCH v2] m25p80: Improve error when the backend file size does not match the device

2022-11-15 Thread Peter Delevoryas
On Tue, Nov 15, 2022 at 04:50:11PM +0100, Philippe Mathieu-Daudé wrote:
> On 15/11/22 16:10, Cédric Le Goater wrote:
> > Currently, when a block backend is attached to a m25p80 device and the
> > associated file size does not match the flash model, QEMU complains
> > with the error message "failed to read the initial flash content".
> > This is confusing for the user.
> > 
> > Use blk_check_size_and_read_all() instead of blk_pread() to improve
> > the reported error.
> > 
> > Signed-off-by: Cédric Le Goater 
> > ---
> >   hw/block/m25p80.c | 4 ++--
> >   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> Reviewed-by: Philippe Mathieu-Daudé 
> 

Thanks Cedric!

Reviewed-by: Peter Delevoryas 



Re: [PATCH 0/1] hw/arm/aspeed: Automatically zero-extend flash images

2022-11-15 Thread Peter Delevoryas
On Tue, Nov 15, 2022 at 02:06:57PM +0100, Cédric Le Goater wrote:
> Hello Peter,
> 
> On 11/14/22 20:08, Peter Delevoryas wrote:
> > I've been using this patch for a long time so that I don't have to use
> > dd to zero-extend stuff all the time. It's just doing what people are
> > doing already, right? I hope it's not controversial.
> 
> I simply run :
> 
>truncate --size 

Ohhh I always forget about that command. That's certainly easier
than what I was doing.

> 
> on the FW file when needed and it is rare because most FW image builders
> know the flash size of the target.

welll my yocto builds don't, I'm not sure we would want them to either?

Because that would be extra data with no value to transfer to the BMC/etc.

flashcp erases the whole flash initially, which is why I don't worry
about providing a firmware image that is only covering the first 30 MB of
flash.

> 
> However, the current error message is confusing and the following could
> be an improvement :
> 
> @@ -1606,6 +1606,13 @@ static void m25p80_realize(SSIPeripheral
>  if (s->blk) {
>  uint64_t perm = BLK_PERM_CONSISTENT_READ |
>  (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 
> 0);
> +
> +if (blk_getlength(s->blk) != s->size) {
> +error_setg(errp, "backend file is too small for flash device %s 
> (%d MB)",
> +   object_class_get_name(OBJECT_CLASS(mc)), s->size >> 
> 20);
> +return;
> +}
> +
>  ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
>  if (ret < 0) {
>  return;
> 
> I can send a patch for the above.

Ohhh yay! Thanks!

> 
> 
> 
> I mostly run the QEMU machines with -snapshot, this hack  :
> 
>   blk_set_allow_write_beyond_eof(s->blk, true);
> 
> makes it work also ...

!!! Ohhh! interesting...that seems more sketchy but certainly simpler.

> 
> 
> 
> 
> Thanks,
> 
> C.
> 
> > One note: I couldn't figure out how to make it work without changing the
> > permissions on the block device to allow truncation. If somebody knows
> > how to avoid the `blk_get_perm`, `blk_set_perm` calls here, let me know!
> > 
> > Thanks,
> > Peter
> > 
> > Peter Delevoryas (1):
> >hw/arm/aspeed: Automatically zero-extend flash images
> > 
> >   hw/arm/aspeed.c | 40 +++-
> >   1 file changed, 39 insertions(+), 1 deletion(-)
> > 
> 



Re: [PATCH 0/1] hw/arm/aspeed: Automatically zero-extend flash images

2022-11-15 Thread Peter Delevoryas
On Tue, Nov 15, 2022 at 10:48:40AM +, Peter Maydell wrote:
> On Mon, 14 Nov 2022 at 19:08, Peter Delevoryas  wrote:
> >
> > I've been using this patch for a long time so that I don't have to use
> > dd to zero-extend stuff all the time. It's just doing what people are
> > doing already, right? I hope it's not controversial.
> 
> We just had a thread about this kind of thing for one of the
> riscv boards (although there the attempted approach was to
> change the size of the flash device to match the provided
> file, rather than changing the file to match the flash device):
> https://lore.kernel.org/qemu-devel/20221107130217.2243815-1-suni...@ventanamicro.com/

Thanks for linking this!

> 
> The short summary is (a) yes, it's controversial and
> (b) if we do something for this we need to have a standard
> approach that we do on all boards, not "some boards do
> some weird magic in different ways from everything else"...

I see, that's ok, I'll investigate option (b) then.

Thanks,
Peter

> 
> thanks
> -- PMM



[PATCH 0/1] hw/arm/aspeed: Automatically zero-extend flash images

2022-11-14 Thread Peter Delevoryas
I've been using this patch for a long time so that I don't have to use
dd to zero-extend stuff all the time. It's just doing what people are
doing already, right? I hope it's not controversial.

One note: I couldn't figure out how to make it work without changing the
permissions on the block device to allow truncation. If somebody knows
how to avoid the `blk_get_perm`, `blk_set_perm` calls here, let me know!

Thanks,
Peter

Peter Delevoryas (1):
  hw/arm/aspeed: Automatically zero-extend flash images

 hw/arm/aspeed.c | 40 +++-
 1 file changed, 39 insertions(+), 1 deletion(-)

-- 
2.38.1




[PATCH 1/1] hw/arm/aspeed: Automatically zero-extend flash images

2022-11-14 Thread Peter Delevoryas
One thing that's really annoying about the Aspeed machines is that you
have to provide a flash image that is the same size as the SPI-NOR flash
device the board uses, or something larger. If you don't, you'll get
this obscure error message:

qemu-system-aarch64: failed to read the initial flash content

Which is just because the file isn't the right size. Zero-extending the
file to 128MB (the largest SPI-NOR flash size) fixes this.

This commit just performs the zero-extend automatically, so people don't
have to maintain bash scripts for it. And if your bash script does this
already, it will be a no-op. And, if your firmware image is larger than
the SPI-NOR device, then it will not truncate it.

Signed-off-by: Peter Delevoryas 
---
 hw/arm/aspeed.c | 40 +++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef72..26450d90db 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -260,6 +260,30 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, 
size_t rom_size,
 rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
 }
 
+static int zero_extend_block_device(BlockBackend *blk, uint64_t size,
+Error **errp)
+{
+uint64_t perm, shared_perm;
+
+blk_get_perm(blk, , _perm);
+
+if (blk_set_perm(blk, BLK_PERM_ALL, BLK_PERM_ALL, errp)) {
+error_append_hint(errp, "Unable to change permissions on block 
device");
+return -1;
+}
+if (blk_truncate(blk, size, true, PREALLOC_MODE_OFF, BDRV_REQ_ZERO_WRITE,
+ errp)) {
+error_append_hint(errp, "Unable to zero-extend block device");
+return -1;
+}
+if (blk_set_perm(blk, perm, shared_perm, errp)) {
+error_append_hint(errp,
+  "Unable to restore permissions on block device");
+/* Ignore error since we successfully extended the device already */
+}
+return 0;
+}
+
 void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
   unsigned int count, int unit0)
 {
@@ -273,10 +297,24 @@ void aspeed_board_init_flashes(AspeedSMCState *s, const 
char *flashtype,
 DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
 qemu_irq cs_line;
 DeviceState *dev;
+AspeedSMCFlash *flash = >flashes[i];
+uint64_t flash_size = memory_region_size(>mmio);
 
 dev = qdev_new(flashtype);
 if (dinfo) {
-qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
+BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+int64_t blk_size = blk_getlength(blk);
+
+if (blk_size > 0 && blk_size < (int64_t)flash_size) {
+Error *err = NULL;
+
+zero_extend_block_device(blk, flash_size, );
+if (err) {
+warn_reportf_err(err, "Error zero-extending MTD drive[%d] "
+ "to flash size", i);
+}
+}
+qdev_prop_set_drive(dev, "drive", blk);
 }
 qdev_realize_and_unref(dev, BUS(s->spi), _fatal);
 
-- 
2.38.1




Re: [RFC PATCH v2 3/3] hw/peci: add support for EndPointConfig reads

2022-09-13 Thread Peter Delevoryas
On Tue, Sep 13, 2022 at 06:21:49PM +, Titus Rwantare wrote:
> Signed-off-by: Titus Rwantare 
> Reviewed-by: Hao Wu 

Reviewed-by: Peter Delevoryas 

> ---
>  hw/peci/peci-client.c  | 63 ++
>  hw/peci/peci-core.c| 44 +++--
>  include/hw/peci/peci.h | 23 +++
>  3 files changed, 128 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/peci/peci-client.c b/hw/peci/peci-client.c
> index 2aa797b5f6..e54735bb53 100644
> --- a/hw/peci/peci-client.c
> +++ b/hw/peci/peci-client.c
> @@ -23,6 +23,64 @@
>  
>  #define PECI_CLIENT_DEFAULT_TEMP 30
>  
> +/* TODO: move this out into a config */
> +static const PECIEndPointConfig spr_config[] = {
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 0,
> +.hdr.func = 2,
> +.hdr.reg = 0xD4,
> +.data = BIT(31)
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 0,
> +.hdr.func = 2,
> +.hdr.reg = 0xD0,
> +.data = BIT(31) | BIT(30)
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 30,
> +.hdr.func = 6,
> +.hdr.reg = 0x84,
> +.data = 0x03FF
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 30,
> +.hdr.func = 6,
> +.hdr.reg = 0x80,
> +.data = 0x
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 30,
> +.hdr.func = 6,
> +.hdr.reg = 0x84,
> +.data = 0x03FF
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 30,
> +.hdr.func = 6,
> +.hdr.reg = 0x80,
> +.data = 0x
> +},
> +};
> +
>  static void peci_client_update_temps(PECIClientDevice *client)
>  {
>  uint8_t temp_cpu = 0;
> @@ -115,7 +173,12 @@ PECIClientDevice *peci_add_client(PECIBus *bus,
>  break;
>  
>  case FAM6_ICELAKE_X:
> +client->revision = 0x40;
> +break;
> +
>  case FAM6_SAPPHIRE_RAPIDS_X:
> +client->endpoint_conf = spr_config;
> +client->num_entries = sizeof(spr_config) / sizeof(spr_config[0]);
>  client->revision = 0x40;
>  client->ucode = 0x8c0004a0;
>  break;
> diff --git a/hw/peci/peci-core.c b/hw/peci/peci-core.c
> index 8210bfa198..0650a03e2d 100644
> --- a/hw/peci/peci-core.c
> +++ b/hw/peci/peci-core.c
> @@ -22,6 +22,47 @@
>  #define PECI_FCS_OK 0
>  #define PECI_FCS_ERR1
>  
> +static PECIEndPointHeader peci_fmt_end_pt_header(PECICmd *pcmd)
> +{
> +uint32_t val = pcmd->rx[7] | (pcmd->rx[8] << 8) | (pcmd->rx[9] << 16) |
> +  (pcmd->rx[10] << 24);
> +
> +PECIEndPointHeader header = {
> +.msg_type = pcmd->rx[1],
> +.addr_type = pcmd->rx[5],
> +.bus = (val >> 20) & 0xFF,
> +.dev = (val >> 15) & 0x1F,
> +.func = (val >> 12) & 0x7,
> +.reg = val & 0xFFF,
> +};
> +
> +return header;
> +}
> +
> +static void peci_rd_endpoint_cfg(PECIClientDevice *client, PECICmd *pcmd)
> +{
> +PECIPkgCfg *resp = (PECIPkgCfg *)pcmd->tx;
> +PECIEndPointHeader req = peci_fmt_end_pt_header(pcmd);
> +PECIEndPointConfig const *c;
> +
> +if (client->endpoint_conf) {
> +for (size_t i = 0; i < client->num_entries; i++) {
> +c = >endpoint_conf[i];
> +
> +if (!memcmp(, >hdr, sizeof(PECIEndPointHeader))) {
> +resp->data = c->data;
> +resp->cc = PECI_DEV_CC_SUCCESS;
> +return;
> +}
> +}
> +}
> +
> +qemu_log_mask(LOG_UNIMP,
> +  "%s: msg_type: 0x%x bus: %u, dev: %u, func: %u, reg: 
> 0x%x\n",
> +  __func__, req.msg_type, req.bus, req.dev, req.func, 
> req.reg);
> +
> +}
> +
>  static void peci_rd_pkg_cfg(PECIClientDevice *client, PECICmd *pcmd)
>  {
>  PECIPkgCfg *resp = (PECIPkgCfg *)pcmd->tx;
> @@ -153,8 +194,7 @@ int peci_handle_cmd(PECIBus *bus, PECICmd *pcmd)
>  break;

Re: [RFC PATCH 1/3] hw/peci: add initial support for PECI

2022-09-13 Thread Peter Delevoryas
On Tue, Sep 13, 2022 at 11:21:16AM -0700, Titus Rwantare wrote:
> On Fri, 9 Sept 2022 at 12:58, Peter Delevoryas  wrote:
> 
> > > +/*
> > > + * PECI Client device
> > > + * Copyright 2021 Google LLC
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> >
> > Not sure, but I think the SPDX license identifier is supposed to be in
> > the first line? Maybe not though. I would have expected:
> >
> 
> That's a Linux thing as far as I can tell. QEMU has it in the top comment.

Oh ok, nevermind then.

> 
> >
> > I'm curious if we really need the CPU family here, or if we could just
> > base everything off the PECI version.
> >
> > The PECI specification doesn't mention the CPU family, does it? Or maybe
> > it does.
> >
> 
> I needed the family info anyway for RdPkgConfig() CPU ID, and thought it
> would be more readable to specify that in the board file than the PECI 
> version.
> We tend to add new machines to QEMU by copying the config of an existing
> machine, I think this way makes it more obvious that this is a field
> that is changing.

Yeah, I think you're right. And looking at the PECI spec, they refer to
families directly when describing new features, so this seems
appropriate.

Reviewed-by: Peter Delevoryas 

> 
> 
> Titus



Re: [RFC PATCH 0/3] Initial PECI bus support

2022-09-13 Thread Peter Delevoryas
On Tue, Sep 13, 2022 at 11:20:57AM -0700, Titus Rwantare wrote:
> On Fri, 9 Sept 2022 at 12:54, Peter Delevoryas  wrote:
> >
> > On Tue, Sep 06, 2022 at 10:05:49PM +, Titus Rwantare wrote:
> ...
> > >
> > > This is something that can also be extended as other parameters arise 
> > > that need
> > > to differ between platforms. So far you can have have different CPUs, 
> > > DIMM counts,
> > > DIMM temperatures here. These fields can also be adjusted at runtime 
> > > through qmp.
> >
> > That looks good to me, seems like the standard way to do it in QEMU.
> >
> > >
> > > A lot of the registers are hard coded, see hw/peci/peci-client.c. I'd 
> > > like to
> > > gauge interest in what potential users would like to be adjustable at 
> > > runtime.
> > > I've not written QEMU models that read config files at runtime, something 
> > > I'd
> > > appreciate guidance on.
> >
> > This part I don't totally understand. I also barely know anything about
> > PECI.
> >
> > Is the register location for things different between CPU generations?
> 
> Some things seem to move between generations and others don't move, someone at
> Intel would know better than I do.
> 
> 
> 
> > If so (and I expect it probably is), why is there only a configuration
> > for Sapphire Rapids, and not for the other ones?
> >
> > Is that because of PECI protocol changes between generations?
> 
> I haven't dug into the other machines because of internal demand, but
> I've found that
> with newer generations, more features get used in addition to existing
> ones. It's
> possible these features existed on older machines.
> 
> 
> 
> > In which case, maybe there needs to be a notion of PECI version
> > somewhere?
> >
> > Also, I don't understand why it would be adjustable at runtime, do we
> > change register locations during execution?
> >
> > I would expect it to be part of the board definition.
> >
> > You could provide a bunch of sample configs for the CPU's that you're
> > testing for, and the board configuration could just select the sample
> > config it is using (corresponding to the CPU model).
> >
> > That's the model I would imagine, but I might be missing some important
> > context here.
> 
> I think it would be nice to have additional registers at runtime, at
> the time of writing,
> I don't know how much of the internal workings of Sapphire Rapids
> Intel is willing to
> share publicly. If users are free to separately define registers, I
> don't then get to
> worry about this. e.g. I'd like to simulate errors from the memory 
> controllers.

Oh ok, yeah I guess making it more dynamic shouldn't really hurt
anything. That sounds ok then.  Also yeah, perhaps keeping the register
definitions separate for privacy concerns is necessary.

Reviewed-by: Peter Delevoryas 

> 
> 
> Titus



Re: [RFC PATCH v2 1/3] hw/peci: add initial support for PECI

2022-09-13 Thread Peter Delevoryas
On Tue, Sep 13, 2022 at 06:21:47PM +, Titus Rwantare wrote:
> PECI - Platform Environment Control Interface
> 
> This commit adds support for reading basic sensor values from a client
> on the PECI bus.
> BMCs can use the PECI wire to get thermal information out of an Intel
> cpu. Additionally, on hardware, various MSRs are exposed over the
> PECI bus. Part of PCI config space is exposed due to Intel posting
> various platform configuration in PCI config space.
> 
> Commands implemented:
> - Ping
> - GetDIB
> - GetTemp
> - GetPkgConfig (partial)
> 
> Commands not implemented:
> - RdIAMSR
> - RdPCIConfig
> - RdPCIConfigLocal
> 
> Signed-off-by: Titus Rwantare 
> Reviewed-by: Hao Wu 
> Reviewed-by: Patrick Venture 

Reviewed-by: Peter Delevoryas 

> ---
>  MAINTAINERS|   7 ++
>  hw/Kconfig |   1 +
>  hw/meson.build |   1 +
>  hw/peci/Kconfig|   2 +
>  hw/peci/meson.build|   1 +
>  hw/peci/peci-client.c  | 230 +
>  hw/peci/peci-core.c| 182 
>  hw/peci/trace-events   |   5 +
>  hw/peci/trace.h|   1 +
>  include/hw/peci/peci.h | 194 ++
>  meson.build|   1 +
>  11 files changed, 625 insertions(+)
>  create mode 100644 hw/peci/Kconfig
>  create mode 100644 hw/peci/meson.build
>  create mode 100644 hw/peci/peci-client.c
>  create mode 100644 hw/peci/peci-core.c
>  create mode 100644 hw/peci/trace-events
>  create mode 100644 hw/peci/trace.h
>  create mode 100644 include/hw/peci/peci.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5ce4227ff6..14ab29679d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3212,6 +3212,13 @@ F: tests/qtest/adm1272-test.c
>  F: tests/qtest/max34451-test.c
>  F: tests/qtest/isl_pmbus_vr-test.c
>  
> +PECI
> +M: Titus Rwantare 
> +S: Maintained
> +F: hw/peci/peci-core.c
> +F: hw/peci/peci-client.c
> +F: include/hw/peci/peci.h
> +
>  Firmware schema specifications
>  M: Philippe Mathieu-Daudé 
>  R: Daniel P. Berrange 
> diff --git a/hw/Kconfig b/hw/Kconfig
> index 38233bbb0f..300ab48127 100644
> --- a/hw/Kconfig
> +++ b/hw/Kconfig
> @@ -24,6 +24,7 @@ source net/Kconfig
>  source nubus/Kconfig
>  source nvme/Kconfig
>  source nvram/Kconfig
> +source peci/Kconfig
>  source pci-bridge/Kconfig
>  source pci-host/Kconfig
>  source pcmcia/Kconfig
> diff --git a/hw/meson.build b/hw/meson.build
> index c7ac7d3d75..340cc88a52 100644
> --- a/hw/meson.build
> +++ b/hw/meson.build
> @@ -28,6 +28,7 @@ subdir('pci')
>  subdir('pci-bridge')
>  subdir('pci-host')
>  subdir('pcmcia')
> +subdir('peci')
>  subdir('rdma')
>  subdir('rtc')
>  subdir('scsi')
> diff --git a/hw/peci/Kconfig b/hw/peci/Kconfig
> new file mode 100644
> index 00..fe4f665d21
> --- /dev/null
> +++ b/hw/peci/Kconfig
> @@ -0,0 +1,2 @@
> +config PECI
> +bool
> diff --git a/hw/peci/meson.build b/hw/peci/meson.build
> new file mode 100644
> index 00..01cfa95abe
> --- /dev/null
> +++ b/hw/peci/meson.build
> @@ -0,0 +1 @@
> +softmmu_ss.add(when: 'CONFIG_PECI', if_true: files('peci-core.c', 
> 'peci-client.c'))
> diff --git a/hw/peci/peci-client.c b/hw/peci/peci-client.c
> new file mode 100644
> index 00..2aa797b5f6
> --- /dev/null
> +++ b/hw/peci/peci-client.c
> @@ -0,0 +1,230 @@
> +/*
> + * PECI Client device
> + * Copyright 2021 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/peci/peci.h"
> +#include "hw/qdev-core.h"
> +#include "hw/qdev-properties.h"
> +#include "migration/vmstate.h"
> +#include "qapi/error.h"
> +#include "qapi/visitor.h"
> +#include "qemu/module.h"
> +#include "qemu/log.h"
> +#include "qom/object.h"
> +
> +/*
> + * A PECI client represents an Intel socket and the peripherals attached to 
> it
> + * that are accessible over the PECI bus.
> + */
> +
> +#define PECI_CLIENT_DEFAULT_TEMP 30
> +
> +static void peci_client_update_temps(PECIClientDevice *client)
> +{
> +uint8_t temp_cpu = 0;
> +for (size_t i = 0; i < client->cpu_cores; i++) {
> +if (temp_cpu < client->core_temp[i]) {
> +temp_cpu = client->core_temp[i];
> +}
> +}
> +client->core_temp_max = -1 * (client->tjmax - temp_cpu);
> +
> +uint8_t temp_dimm = 0;
> +for (size_t i = 0; i < client->dimms; i++) {
> +if (temp_dimm < client->dimm

Re: [RFC PATCH 2/3] hw/peci: add PECI support for NPCM7xx BMCs

2022-09-09 Thread Peter Delevoryas
On Tue, Sep 06, 2022 at 10:05:51PM +, Titus Rwantare wrote:
> This allows BMC firmware for npcm7xx BMCs to talk to a PECI client
> in qemu.
> 
> Signed-off-by: Titus Rwantare 
> Reviewed-by: Patrick Venture 

Looks good to me!

Reviewed-by: Peter Delevoryas 

> ---
>  MAINTAINERS|   3 +-
>  hw/arm/Kconfig |   1 +
>  hw/arm/npcm7xx.c   |   9 ++
>  hw/peci/meson.build|   1 +
>  hw/peci/npcm7xx_peci.c | 204 +
>  hw/peci/trace-events   |   5 +
>  include/hw/arm/npcm7xx.h   |   2 +
>  include/hw/peci/npcm7xx_peci.h |  37 ++
>  8 files changed, 261 insertions(+), 1 deletion(-)
>  create mode 100644 hw/peci/npcm7xx_peci.c
>  create mode 100644 include/hw/peci/npcm7xx_peci.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 14ab29679d..f87dfe5bfa 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2959,7 +2959,7 @@ R: Paolo Bonzini 
>  R: Bandan Das 
>  R: Stefan Hajnoczi 
>  R: Thomas Huth 
> -R: Darren Kenny  
> +R: Darren Kenny 
>  R: Qiuhao Li 
>  S: Maintained
>  F: tests/qtest/fuzz/
> @@ -3218,6 +3218,7 @@ S: Maintained
>  F: hw/peci/peci-core.c
>  F: hw/peci/peci-client.c
>  F: include/hw/peci/peci.h
> +F: hw/peci/npcm7xx_peci.c
>  
>  Firmware schema specifications
>  M: Philippe Mathieu-Daudé 
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 15fa79afd3..cb38c6c88f 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -408,6 +408,7 @@ config NPCM7XX
>  select SSI
>  select UNIMP
>  select PCA954X
> +select PECI
>  
>  config FSL_IMX25
>  bool
> diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
> index d85cc02765..d408dd7eb4 100644
> --- a/hw/arm/npcm7xx.c
> +++ b/hw/arm/npcm7xx.c
> @@ -45,6 +45,7 @@
>  #define NPCM7XX_CLK_BA  (0xf0801000)
>  #define NPCM7XX_MC_BA   (0xf0824000)
>  #define NPCM7XX_RNG_BA  (0xf000b000)
> +#define NPCM7XX_PECI_BA (0xf010)
>  
>  /* USB Host modules */
>  #define NPCM7XX_EHCI_BA (0xf0806000)
> @@ -83,6 +84,7 @@ enum NPCM7xxInterrupt {
>  NPCM7XX_UART1_IRQ,
>  NPCM7XX_UART2_IRQ,
>  NPCM7XX_UART3_IRQ,
> +NPCM7XX_PECI_IRQ= 6,
>  NPCM7XX_EMC1RX_IRQ  = 15,
>  NPCM7XX_EMC1TX_IRQ,
>  NPCM7XX_MMC_IRQ = 26,
> @@ -445,6 +447,7 @@ static void npcm7xx_init(Object *obj)
>  }
>  
>  object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
> +object_initialize_child(obj, "peci", >peci, TYPE_NPCM7XX_PECI);
>  }
>  
>  static void npcm7xx_realize(DeviceState *dev, Error **errp)
> @@ -715,6 +718,12 @@ static void npcm7xx_realize(DeviceState *dev, Error 
> **errp)
>  sysbus_connect_irq(SYS_BUS_DEVICE(>mmc), 0,
>  npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
>  
> + /* PECI */
> +sysbus_realize(SYS_BUS_DEVICE(>peci), _abort);
> +sysbus_mmio_map(SYS_BUS_DEVICE(>peci), 0, NPCM7XX_PECI_BA);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>peci), 0,
> +   npcm7xx_irq(s, NPCM7XX_PECI_IRQ));
> +
>  create_unimplemented_device("npcm7xx.shm",  0xc0001000,   4 * 
> KiB);
>  create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * 
> KiB);
>  create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * 
> KiB);
> diff --git a/hw/peci/meson.build b/hw/peci/meson.build
> index 01cfa95abe..ee033eb915 100644
> --- a/hw/peci/meson.build
> +++ b/hw/peci/meson.build
> @@ -1 +1,2 @@
>  softmmu_ss.add(when: 'CONFIG_PECI', if_true: files('peci-core.c', 
> 'peci-client.c'))
> +softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_peci.c'))
> diff --git a/hw/peci/npcm7xx_peci.c b/hw/peci/npcm7xx_peci.c
> new file mode 100644
> index 00..17a2642898
> --- /dev/null
> +++ b/hw/peci/npcm7xx_peci.c
> @@ -0,0 +1,204 @@
> +/*
> + * Nuvoton NPCM7xx PECI Module
> + *
> + * Copyright 2021 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/peci/npcm7xx_peci.h"
> +#include "qemu/bitops.h"
> +#include "qemu/log.h"
> +#include "qemu/units.h"
> +#include "trace.h"
> +
> +#define PECI_CTL_STS0
> +#define PECI_CTL_STS_DONE_EN  BIT(6)
> +#define PECI_CTL_STS_ABRT_ERR BIT(4)
> +#define PECI_CTL_STS_CRC_ERR  BIT(3)
> +#define PECI_CTL_STS_DONE BIT(1)
> +#define PECI_CTL_STS_START_BUSY   BIT(0)
> +#define PECI_RD_LENGTH  0x4
> +#define PE

Re: [RFC PATCH 1/3] hw/peci: add initial support for PECI

2022-09-09 Thread Peter Delevoryas
On Tue, Sep 06, 2022 at 10:05:50PM +, Titus Rwantare wrote:
> PECI - Platform Environment Control Interface
> 
> This commit adds support for reading basic sensor values from a client
> on the PECI bus.
> BMCs can use the PECI wire to get thermal information out of an Intel
> cpu. Additionally, on hardware, various MSRs are exposed over the
> PECI bus. Part of PCI config space is exposed due to Intel posting
> various platform configuration in PCI config space.
> 
> Commands implemented:
> - Ping
> - GetDIB
> - GetTemp
> - GetPkgConfig (partial)
> 
> Commands not implemented:
> - RdIAMSR
> - RdPCIConfig
> - RdPCIConfigLocal
> 
> Signed-off-by: Titus Rwantare 
> Reviewed-by: Hao Wu 
> Reviewed-by: Patrick Venture 
> ---
>  MAINTAINERS|   7 ++
>  hw/Kconfig |   1 +
>  hw/meson.build |   1 +
>  hw/peci/Kconfig|   2 +
>  hw/peci/meson.build|   1 +
>  hw/peci/peci-client.c  | 230 +
>  hw/peci/peci-core.c| 182 
>  hw/peci/trace-events   |   5 +
>  hw/peci/trace.h|   1 +
>  include/hw/peci/peci.h | 194 ++
>  meson.build|   1 +
>  11 files changed, 625 insertions(+)
>  create mode 100644 hw/peci/Kconfig
>  create mode 100644 hw/peci/meson.build
>  create mode 100644 hw/peci/peci-client.c
>  create mode 100644 hw/peci/peci-core.c
>  create mode 100644 hw/peci/trace-events
>  create mode 100644 hw/peci/trace.h
>  create mode 100644 include/hw/peci/peci.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5ce4227ff6..14ab29679d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3212,6 +3212,13 @@ F: tests/qtest/adm1272-test.c
>  F: tests/qtest/max34451-test.c
>  F: tests/qtest/isl_pmbus_vr-test.c
>  
> +PECI
> +M: Titus Rwantare 
> +S: Maintained
> +F: hw/peci/peci-core.c
> +F: hw/peci/peci-client.c
> +F: include/hw/peci/peci.h
> +
>  Firmware schema specifications
>  M: Philippe Mathieu-Daudé 
>  R: Daniel P. Berrange 
> diff --git a/hw/Kconfig b/hw/Kconfig
> index 38233bbb0f..300ab48127 100644
> --- a/hw/Kconfig
> +++ b/hw/Kconfig
> @@ -24,6 +24,7 @@ source net/Kconfig
>  source nubus/Kconfig
>  source nvme/Kconfig
>  source nvram/Kconfig
> +source peci/Kconfig
>  source pci-bridge/Kconfig
>  source pci-host/Kconfig
>  source pcmcia/Kconfig
> diff --git a/hw/meson.build b/hw/meson.build
> index c7ac7d3d75..340cc88a52 100644
> --- a/hw/meson.build
> +++ b/hw/meson.build
> @@ -28,6 +28,7 @@ subdir('pci')
>  subdir('pci-bridge')
>  subdir('pci-host')
>  subdir('pcmcia')
> +subdir('peci')
>  subdir('rdma')
>  subdir('rtc')
>  subdir('scsi')
> diff --git a/hw/peci/Kconfig b/hw/peci/Kconfig
> new file mode 100644
> index 00..fe4f665d21
> --- /dev/null
> +++ b/hw/peci/Kconfig
> @@ -0,0 +1,2 @@
> +config PECI
> +bool
> diff --git a/hw/peci/meson.build b/hw/peci/meson.build
> new file mode 100644
> index 00..01cfa95abe
> --- /dev/null
> +++ b/hw/peci/meson.build
> @@ -0,0 +1 @@
> +softmmu_ss.add(when: 'CONFIG_PECI', if_true: files('peci-core.c', 
> 'peci-client.c'))
> diff --git a/hw/peci/peci-client.c b/hw/peci/peci-client.c
> new file mode 100644
> index 00..2aa797b5f6
> --- /dev/null
> +++ b/hw/peci/peci-client.c
> @@ -0,0 +1,230 @@
> +/*
> + * PECI Client device
> + * Copyright 2021 Google LLC
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later

Not sure, but I think the SPDX license identifier is supposed to be in
the first line? Maybe not though. I would have expected:

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * PECI Client device
 *
 * Copyright 2021 Google LLC
 */

> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/peci/peci.h"
> +#include "hw/qdev-core.h"
> +#include "hw/qdev-properties.h"
> +#include "migration/vmstate.h"
> +#include "qapi/error.h"
> +#include "qapi/visitor.h"
> +#include "qemu/module.h"
> +#include "qemu/log.h"
> +#include "qom/object.h"
> +
> +/*
> + * A PECI client represents an Intel socket and the peripherals attached to 
> it
> + * that are accessible over the PECI bus.
> + */
> +
> +#define PECI_CLIENT_DEFAULT_TEMP 30
> +
> +static void peci_client_update_temps(PECIClientDevice *client)
> +{
> +uint8_t temp_cpu = 0;
> +for (size_t i = 0; i < client->cpu_cores; i++) {
> +if (temp_cpu < client->core_temp[i]) {
> +temp_cpu = client->core_temp[i];
> +}
> +}
> +client->core_temp_max = -1 * (client->tjmax - temp_cpu);
> +
> +uint8_t temp_dimm = 0;
> +for (size_t i = 0; i < client->dimms; i++) {
> +if (temp_dimm < client->dimm_temp[i]) {
> +temp_dimm = client->dimm_temp[i];
> +}
> +}
> +client->dimm_temp_max = temp_dimm;
> +}
> +
> +PECIClientDevice *peci_get_client(PECIBus *bus, uint8_t addr)
> +{
> +PECIClientDevice *client;
> +BusChild *var;
> +
> +QTAILQ_FOREACH(var, >qbus.children, sibling) {
> +DeviceState *dev = var->child;
> +client = PECI_CLIENT(dev);
> +

Re: [RFC PATCH 0/3] Initial PECI bus support

2022-09-09 Thread Peter Delevoryas
On Tue, Sep 06, 2022 at 10:05:49PM +, Titus Rwantare wrote:
> The Platform Environment Control Interface (PECI), is a way for Intel
> processors to communicate with management controllers.
> 
> This series of patches simulate some PECI subsystem functionality. This
> work is currently used against Nuvoton 7xx BMC, but it can easily be
> extended to support Aspeed BMCs. Most of the functionality is derived
> from PECI support in openbmc. See https://github.com/openbmc/libpeci
> 
> The main consumer of this work is openbmc, so functionality not
> exercised by the openbmc/libpeci is unlikely to be present here.
> 
> peci-core.c is an attempt to split out functionality defined by the
> spec. Anything that is not expected to change between BMC vendors.
> 
> The following commands have some support:
> Ping()
> GetDIB()
> GetTemp()
> ~RdPkgConfig()
> ~RdEndPtConfig()
> 
> To be implemented:
> RdIAMSR()
> RdPCIConfig()
> RdPCIConfigLocal()
> 
> Currently, in the board file during bmc_init() one may specify defaults
> as follows:
> 
> static void my_machine_peci_init(NPCM7xxState *soc)
> {
> PECIBus *peci_bus = npcm7xx_peci_get_bus(soc);
> DeviceState *dev;
> 
> /* per socket properties - both sockets are identical in this case */
> PECIClientProperties peci_props = {
> .cpu_family = FAM6_SAPPHIRE_RAPIDS_X,
> .cpus = 56,
> .dimms = 16
> };
> 
> /* socket 0 - with example setting a few of the cpu and dimm temperatures 
> in millidegrees */
> dev = DEVICE(peci_add_client(peci_bus, 0x30, _props));
> object_property_set_uint(OBJECT(dev), "cpu_temp[0]", 3, _abort);
> object_property_set_uint(OBJECT(dev), "cpu_temp[2]", 35000, _abort);
> object_property_set_uint(OBJECT(dev), "dimm_temp[1]", 4, 
> _abort);
> object_property_set_uint(OBJECT(dev), "dimm_temp[8]", 36000, 
> _abort);
> 
> /* socket 1 */
> dev = DEVICE(peci_add_client(peci_bus, 0x31, _props));
> object_property_set_uint(OBJECT(dev), "cpu_temp[9]", 5, _abort);
> object_property_set_uint(OBJECT(dev), "dimm_temp[0]", 31000, 
> _abort);
> object_property_set_uint(OBJECT(dev), "dimm_temp[14]", 36000, 
> _abort);
> ...
> }
> 
> This is something that can also be extended as other parameters arise that 
> need
> to differ between platforms. So far you can have have different CPUs, DIMM 
> counts,
> DIMM temperatures here. These fields can also be adjusted at runtime through 
> qmp.

That looks good to me, seems like the standard way to do it in QEMU.

> 
> A lot of the registers are hard coded, see hw/peci/peci-client.c. I'd like to
> gauge interest in what potential users would like to be adjustable at runtime.
> I've not written QEMU models that read config files at runtime, something I'd
> appreciate guidance on.

This part I don't totally understand. I also barely know anything about
PECI.

Is the register location for things different between CPU generations?

If so (and I expect it probably is), why is there only a configuration
for Sapphire Rapids, and not for the other ones?

Is that because of PECI protocol changes between generations?

In which case, maybe there needs to be a notion of PECI version
somewhere?

Also, I don't understand why it would be adjustable at runtime, do we
change register locations during execution?

I would expect it to be part of the board definition.

You could provide a bunch of sample configs for the CPU's that you're
testing for, and the board configuration could just select the sample
config it is using (corresponding to the CPU model).

That's the model I would imagine, but I might be missing some important
context here.

Thanks,
Peter

> 
> Thanks all
> 
> Titus Rwantare (3):
>   hw/peci: add initial support for PECI
>   hw/peci: add PECI support for NPCM7xx BMCs
>   hw/peci: add support for EndPointConfig reads
> 
>  MAINTAINERS|  10 +-
>  hw/Kconfig |   1 +
>  hw/arm/Kconfig |   1 +
>  hw/arm/npcm7xx.c   |   9 +
>  hw/meson.build |   1 +
>  hw/peci/Kconfig|   2 +
>  hw/peci/meson.build|   2 +
>  hw/peci/npcm7xx_peci.c | 204 +++
>  hw/peci/peci-client.c  | 293 +
>  hw/peci/peci-core.c| 222 +
>  hw/peci/trace-events   |  10 ++
>  hw/peci/trace.h|   1 +
>  include/hw/arm/npcm7xx.h   |   2 +
>  include/hw/peci/npcm7xx_peci.h |  37 +
>  include/hw/peci/peci.h | 217 
>  meson.build|   1 +
>  16 files changed, 1012 insertions(+), 1 deletion(-)
>  create mode 100644 hw/peci/Kconfig
>  create mode 100644 hw/peci/meson.build
>  create mode 100644 hw/peci/npcm7xx_peci.c
>  create mode 100644 hw/peci/peci-client.c
>  create mode 100644 hw/peci/peci-core.c
>  create mode 100644 hw/peci/trace-events
>  

Re: [RFC PATCH 3/3] hw/peci: add support for EndPointConfig reads

2022-09-09 Thread Peter Delevoryas
On Tue, Sep 06, 2022 at 10:05:52PM +, Titus Rwantare wrote:
> Signed-off-by: Titus Rwantare 
> Reviewed-by: Hao Wu 
> ---
>  hw/peci/peci-client.c  | 63 ++
>  hw/peci/peci-core.c| 44 +++--
>  include/hw/peci/peci.h | 23 +++
>  3 files changed, 128 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/peci/peci-client.c b/hw/peci/peci-client.c
> index 2aa797b5f6..8d9248 100644
> --- a/hw/peci/peci-client.c
> +++ b/hw/peci/peci-client.c
> @@ -23,6 +23,64 @@
>  
>  #define PECI_CLIENT_DEFAULT_TEMP 30
>  
> +/* TODO: move this out into a config */
> +static const PECIEndPtConfig spr_config[] = {
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 0,
> +.hdr.func = 2,
> +.hdr.reg = 0xD4,
> +.data = BIT(31)
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 0,
> +.hdr.func = 2,
> +.hdr.reg = 0xD0,
> +.data = BIT(31) | BIT(30)
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 30,
> +.hdr.func = 6,
> +.hdr.reg = 0x84,
> +.data = 0x03FF
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 30,
> +.hdr.func = 6,
> +.hdr.reg = 0x80,
> +.data = 0x
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 30,
> +.hdr.func = 6,
> +.hdr.reg = 0x84,
> +.data = 0x03FF
> +},
> +{
> +.hdr.msg_type = LOCAL_PCI_CFG,
> +.hdr.addr_type = 0x4,
> +.hdr.bus = 31,
> +.hdr.dev = 30,
> +.hdr.func = 6,
> +.hdr.reg = 0x80,
> +.data = 0x
> +},
> +};
> +
>  static void peci_client_update_temps(PECIClientDevice *client)
>  {
>  uint8_t temp_cpu = 0;
> @@ -115,7 +173,12 @@ PECIClientDevice *peci_add_client(PECIBus *bus,
>  break;
>  
>  case FAM6_ICELAKE_X:
> +client->revision = 0x40;
> +break;
> +
>  case FAM6_SAPPHIRE_RAPIDS_X:
> +client->endpt_conf = spr_config;
> +client->num_entries = sizeof(spr_config) / sizeof(spr_config[0]);
>  client->revision = 0x40;
>  client->ucode = 0x8c0004a0;
>  break;
> diff --git a/hw/peci/peci-core.c b/hw/peci/peci-core.c
> index 8210bfa198..a961ae51f3 100644
> --- a/hw/peci/peci-core.c
> +++ b/hw/peci/peci-core.c
> @@ -22,6 +22,47 @@
>  #define PECI_FCS_OK 0
>  #define PECI_FCS_ERR1
>  
> +static PECIEndPtHeader peci_fmt_end_pt_header(PECICmd *pcmd)
> +{
> +uint32_t val = pcmd->rx[7] | (pcmd->rx[8] << 8) | (pcmd->rx[9] << 16) |
> +  (pcmd->rx[10] << 24);
> +
> +PECIEndPtHeader header = {
> +.msg_type = pcmd->rx[1],
> +.addr_type = pcmd->rx[5],
> +.bus = (val >> 20) & 0xFF,
> +.dev = (val >> 15) & 0x1F,
> +.func = (val >> 12) & 0x7,
> +.reg = val & 0xFFF,
> +};
> +
> +return header;
> +}
> +
> +static void peci_rd_endpt_cfg(PECIClientDevice *client, PECICmd *pcmd)
> +{
> +PECIPkgCfg *resp = (PECIPkgCfg *)pcmd->tx;
> +PECIEndPtHeader req = peci_fmt_end_pt_header(pcmd);
> +PECIEndPtConfig const *c;
> +
> +if (client->endpt_conf) {
> +for (size_t i = 0; i < client->num_entries; i++) {
> +c = >endpt_conf[i];
> +
> +if (!memcmp(, >hdr, sizeof(PECIEndPtHeader))) {
> +resp->data = c->data;
> +resp->cc = PECI_DEV_CC_SUCCESS;
> +return;
> +}
> +}
> +}
> +
> +qemu_log_mask(LOG_UNIMP,
> +  "%s: msg_type: 0x%x bus: %u, dev: %u, func: %u, reg: 
> 0x%x\n",
> +  __func__, req.msg_type, req.bus, req.dev, req.func, 
> req.reg);
> +
> +}
> +
>  static void peci_rd_pkg_cfg(PECIClientDevice *client, PECICmd *pcmd)
>  {
>  PECIPkgCfg *resp = (PECIPkgCfg *)pcmd->tx;
> @@ -153,8 +194,7 @@ int peci_handle_cmd(PECIBus *bus, PECICmd *pcmd)
>  break;
>  
>  case PECI_CMD_RD_END_PT_CFG:
> -qemu_log_mask(LOG_UNIMP, "%s: unimplemented CMD_RD_END_PT_CFG\n",
> -  __func__);
> +peci_rd_endpt_cfg(client, pcmd);
>  break;
>  
>  default:
> diff --git a/include/hw/peci/peci.h b/include/hw/peci/peci.h
> index 1a0abe65cd..4fb2fc236e 100644
> --- a/include/hw/peci/peci.h
> +++ b/include/hw/peci/peci.h
> @@ -112,6 +112,26 @@ typedef struct PECITempTarget {
>  uint8_t tjmax;
>  } PECITempTarget;
>  
> +typedef enum PECIEndPtType {
> +LOCAL_PCI_CFG = 3,
> +PCI_CFG,
> +MMIO_BDF,
> +} PECIEndPtType;
> +
> +typedef 

Re: slirp: Can I get IPv6-only DHCP working?

2022-08-25 Thread Peter Delevoryas
On Fri, Aug 26, 2022 at 12:56:10AM +0200, Samuel Thibault wrote:
> Hello,
> 
> Peter Delevoryas, le jeu. 25 août 2022 15:38:53 -0700, a ecrit:
> > It seems like there's support for an IPv6 dns proxy, and there's literally a
> > file called "dhcpv6.c" in slirp, but it has a comment saying it only 
> > supports
> > whatever is necessary for TFTP network boot I guess.
> 
> For which DNS support is welcome :)
> 
> > Maybe there's no support then?
> 
> It seems there is:
> 
> if (ri.want_dns) {
> *resp++ = OPTION_DNS_SERVERS >> 8; /* option-code high byte */
> *resp++ = OPTION_DNS_SERVERS; /* option-code low byte */
> *resp++ = 0; /* option-len high byte */
> *resp++ = 16; /* option-len low byte */
> memcpy(resp, >vnameserver_addr6, 16);
> resp += 16;
> }

Well, that's great, but actually I just care about whether slirp supports DHCPv6
address requests. Sorry if I didn't explain that properly.

My goal is to run:

qemu-system-arm -machine fby35-bmc -nographic -mtdblock image-bmc \
-net nic,model=ftgmac100,netdev=nic \
-netdev user,id=nic,hostfwd=::-:22

And then see that the BMC received an IPv6 address assignment.

But, slirp currently just supports IP address assignment through BOOTP?  I
didn't realize that until looking a little closer at the code. But, since the
DHCPv6 hook "dhcpv6_input" is already there, maybe I can just get something
going through there? I suppose I might need some IPv6 NDP packets to work too,
to ssh through a hostfwd port.

root@bmc-oob:~# ifconfig eth0
eth0  Link encap:Ethernet  HWaddr FA:CE:B0:02:20:22
  inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
  inet6 addr: fec0::f8ce:b0ff:fe02:2022/64 Scope:Site
  inet6 addr: fe80::f8ce:b0ff:fe02:2022/64 Scope:Link
  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
  RX packets:107 errors:0 dropped:0 overruns:0 frame:0
  TX packets:136 errors:0 dropped:0 overruns:0 carrier:0
  collisions:0 txqueuelen:1000
  RX bytes:13316 (13.0 KiB)  TX bytes:10022 (9.7 KiB)
  Interrupt:33

Anyways, I'll do some more investigation on my own, thanks!
Peter

> 
> Samuel



slirp: Can I get IPv6-only DHCP working?

2022-08-25 Thread Peter Delevoryas
I'm having a hard time figuring this out from looking at the code and the
user-level help options.

It seems like there's support for an IPv6 dns proxy, and there's literally a
file called "dhcpv6.c" in slirp, but it has a comment saying it only supports
whatever is necessary for TFTP network boot I guess. Maybe there's no support
then? I'm interested in adding it, if that's the case.

Thanks,
Peter



  1   2   3   4   >