Re: [PATCH] misc/pca955*: Move models under hw/gpio

2024-03-25 Thread Andrew Jeffery
On Mon, 2024-03-25 at 14:48 +0100, Cédric Le Goater wrote:
> The PCA9552 and PCA9554 devices are both I2C GPIO controllers and the
> PCA9552 also can drive LEDs. Do all the necessary adjustments to move
> the models under hw/gpio.
> 
> Cc: Glenn Miles 
> Signed-off-by: Cédric Le Goater 

Acked-by: Andrew Jeffery 



Re: [PATCH 22/33] hw/arm/aspeed_ast2600: Let the A7MPcore create/wire the CPU cores

2024-01-01 Thread Andrew Jeffery
On Tue, 2023-12-12 at 17:29 +0100, Philippe Mathieu-Daudé wrote:
> Set the properties on the a7mpcore object to let it create and
> wire the CPU cores. Remove the redundant code.
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Andrew Jeffery 



Re: [PATCH-for-9.0 20/25] hw: Simplify memory_region_init_ram() calls

2023-11-26 Thread Andrew Jeffery
On Mon, 2023-11-20 at 22:32 +0100, Philippe Mathieu-Daudé wrote:
> Mechanical change using the following coccinelle script:
> 
> @@
> expression mr, owner, arg3, arg4, errp;
> @@
> -   memory_region_init_ram(mr, owner, arg3, arg4, );
> if (
> -   errp
> +   !memory_region_init_ram(mr, owner, arg3, arg4, )
> ) {
> ...
> return;
> }
> 
> and removing the local Error variable.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/arm/aspeed_ast2400.c | 6 ++
>  hw/arm/aspeed_ast2600.c | 6 ++

For my own benefit it looks like the motivating thread for this series
is: 

https://lore.kernel.org/qemu-devel/936e1ac4-cef8-08b4-c688-e5b1e0572...@linaro.org/

Anyway,

Reviewed-by: Andrew Jeffery  # aspeed



Re: [PATCH v3 2/2] misc/pca9552: Let external devices set pca9552 inputs

2023-10-27 Thread Andrew Jeffery
On Tue, 2023-10-24 at 13:11 -0500, Glenn Miles wrote:
> Allow external devices to drive pca9552 input pins by adding
> input GPIO's to the model.  This allows a device to connect
> its output GPIO's to the pca9552 input GPIO's.
> 
> In order for an external device to set the state of a pca9552
> pin, the pin must first be configured for high impedance (LED
> is off).  If the pca9552 pin is configured to drive the pin low
> (LED is on), then external input will be ignored.
> 
> Here is a table describing the logical state of a pca9552 pin
> given the state being driven by the pca9552 and an external device:
> 
>PCA9552
>Configured
>State
> 
>   | Hi-Z | Low |
> --+--+-+
>   External   Hi-Z |  Hi  | Low |
>   Device--+--+-+
>   State  Low  |  Low | Low |
> --+--+-----+
> 
> Signed-off-by: Glenn Miles 

Reviewed-by: Andrew Jeffery 



Re: [PATCH v2] misc/led: LED state is set opposite of what is expected

2023-10-27 Thread Andrew Jeffery
On Tue, 2023-10-24 at 14:11 -0500, Glenn Miles wrote:
> Testing of the LED state showed that when the LED polarity was
> set to GPIO_POLARITY_ACTIVE_LOW and a low logic value was set on
> the input GPIO of the LED, the LED was being turn off when it was
> expected to be turned on.
> 
> Signed-off-by: Glenn Miles 

Reviewed-by: Andrew Jeffery 



Re: [PATCH v6 06/10] hw/fsi: Aspeed APB2OPB interface

2023-10-26 Thread Andrew Jeffery
On Thu, 2023-10-26 at 10:27 -0500, Ninad Palsule wrote:
> Hello Cedric,
> 
> 
> On 10/24/23 10:21, Cédric Le Goater wrote:
> > On 10/24/23 17:00, Ninad Palsule wrote:
> > > Hello Cedric,
> > > 
> > > On 10/24/23 02:46, Cédric Le Goater wrote:
> > > > and the fsi_opb_* routines are useless to me.
> > > We are trying to keep the separation between OPB implementation and 
> > > interface hence we have all those fsi_opb_*. I feel that we should 
> > > keep as it is so that future extensions will be easier. Please let me 
> > > know.
> > 
> > Well, I can't really tell because I don't know enough about FSI :/
> > 
> > The models look fragile and I have spent already a lot of time trying
> > to untangle what they are trying to do. Please ask your teammates or
> > let's see in the next QEMU cycle.
> 
> I have decided to go with the approach you suggested and it looks much 
> better. Fixed it.

I intended to reply to this before Ninad sent out v7, but life
intervened.

If we can't justify it with the code we have now I think it's right to
pull it out. Add the code to support the things we're trying to do when
we need to do them. As long as we don't do anything that precludes us
from adding that code later (and I can't really imagine how we'd corner
ourselves like that).

We should bear in mind I wrote the initial models several years ago in
the space of about a week while I was trying to learn FSI (and more
deeply about the QEMU bus and address space modelling). I think I was
doing that to unblock some CI due to the introduction of the kernel
driver for the Aspeed FSI hardware. The models were pretty rough -
prior to all this review the code reflected my hazy understanding of
the problems. I didn't get time to remove the complexities introduced
by my misunderstandings, and now it's been so long that I'm not much
help with fixing them.

Andrew



Re: [PATCH] MAINTAINERS: aspeed: Update Andrew's email address

2023-10-25 Thread Andrew Jeffery
On Wed, 2023-10-25 at 10:57 +0200, Cédric Le Goater wrote:
> On 10/24/23 11:36, Cédric Le Goater wrote:
> > On 9/25/23 08:22, Andrew Jeffery wrote:
> > > I've changed employers, have company email that deals with patch-based
> > > workflows without too much of a headache, and am trying to steer some
> > > content out of my personal mail.
> > > 
> > > Signed-off-by: Andrew Jeffery 
> > > ---
> > > 
> > > Hi Cédric, do you mind including this in your Aspeed queue?
> > 
> > 
> > I am not sure to send an Aspeed PR. May be this change could go
> > through qemu-trivial ?
> 
> After all, I will send an Aspeed PR. Don't bother.

Thanks!



Re: [PATCH] eeprom_at24c: Model 8-bit data addressing for 16-bit devices

2023-10-25 Thread Andrew Jeffery
On Wed, 2023-10-25 at 11:22 +0200, Klaus Jensen wrote:
> On Oct 25 11:14, Cédric Le Goater wrote:
> > It seems that the "at24c-eeprom" model doesn't have a maintainer. Until
> > this is sorted out, may be this change could go through the NVMe queue
> > since it is related.
> > 
> 
> I can, but I'm not that confident on determining if we choose to
> implement this behavior broadly. I have no qualms, but someone who works
> more with embedded stuff might?

What are the feelings on putting the behaviour behind a flag? We could
add it as a property that we can set, e.g. when defining a machine.

Andrew



Re: [PATCH v2 1/3] misc/pca9552: Fix inverted input status

2023-10-23 Thread Andrew Jeffery
On Fri, 2023-10-20 at 13:23 -0500, Glenn Miles wrote:
> The pca9552 INPUT0 and INPUT1 registers are supposed to
> hold the logical values of the LED pins.  A logical 0
> should be seen in the INPUT0/1 registers for a pin when
> its corresponding LSn bits are set to 0, which is also
> the state needed for turning on an LED in a typical
> usage scenario.  Existing code was doing the opposite
> and setting INPUT0/1 bit to a 1 when the LSn bit was
> set to 0, so this commit fixes that.
> 
> Signed-off-by: Glenn Miles 

I sent a Reviewed-by tag for v1, don't forget to collect those on your
patches before sending out a new set. Something for next time :)

Anyway,

Reviewed-by: Andrew Jeffery 




Re: [PATCH v2 3/3] misc/pca9552: Only update output GPIOs if state changed

2023-10-23 Thread Andrew Jeffery
On Fri, 2023-10-20 at 13:23 -0500, Glenn Miles wrote:
> The pca9552 code was updating output GPIO states whenever
> the pin state was updated even if the state did not change.
> This commit adds a check so that we only update the GPIO
> output when the pin state actually changes.

Given this is intertwined with patch 2/3 that adds the input mode
capability, I think they should be squashed together?

> 
> Signed-off-by: Glenn Miles 
> ---
> 
> New commit in v2
> 
>  hw/misc/pca9552.c | 25 ++---
>  1 file changed, 18 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
> index ed814d1f98..4ed6903404 100644
> --- a/hw/misc/pca9552.c
> +++ b/hw/misc/pca9552.c
> @@ -112,14 +112,15 @@ static void pca955x_update_pin_input(PCA955xState *s)
>  
>  for (i = 0; i < k->pin_count; i++) {
>  uint8_t input_reg = PCA9552_INPUT0 + (i / 8);
> -uint8_t input_shift = (i % 8);
> +uint8_t bit_mask = 1 << (i % 8);
>  uint8_t config = pca955x_pin_get_config(s, i);
> +uint8_t old_value = s->regs[input_reg] & bit_mask;
> +uint8_t new_value;
>  
>  switch (config) {
>  case PCA9552_LED_ON:
>  /* Pin is set to 0V to turn on LED */
> -qemu_set_irq(s->gpio_out[i], 0);
> -s->regs[input_reg] &= ~(1 << input_shift);
> +s->regs[input_reg] &= ~bit_mask;
>  break;
>  case PCA9552_LED_OFF:
>  /*
> @@ -128,11 +129,9 @@ static void pca955x_update_pin_input(PCA955xState *s)
>   * external device drives it low.
>   */
>  if (s->ext_state[i] == PCA9552_PIN_LOW) {
> -qemu_set_irq(s->gpio_out[i], 0);
> -s->regs[input_reg] &= ~(1 << input_shift);
> +s->regs[input_reg] &= ~bit_mask;
>  } else {
> -qemu_set_irq(s->gpio_out[i], 1);
> -s->regs[input_reg] |= 1 << input_shift;
> +s->regs[input_reg] |=  bit_mask;
>  }
>  break;
>  case PCA9552_LED_PWM0:
> @@ -141,6 +140,18 @@ static void pca955x_update_pin_input(PCA955xState *s)
>  default:
>  break;
>  }
> +
> +/* update irq state only if pin state changed */
> +new_value = s->regs[input_reg] & bit_mask;
> +if (new_value != old_value) {
> +if (new_value) {
> +/* changed from 0 to 1 */
> +qemu_set_irq(s->gpio_out[i], 1);
> +} else {
> +/* changed from 1 to 0 */
> +qemu_set_irq(s->gpio_out[i], 0);
> +}

Slightly code-golf-y, but the inner if-else here may be compressed to:

qemu_set_irq(s->gpio_out[i], !!new_value);

Andrew



Re: [PATCH 1/2] misc/pca9552: Fix inverted input status

2023-10-23 Thread Andrew Jeffery
On Fri, 2023-10-20 at 11:32 -0500, Miles Glenn wrote:
> On Fri, 2023-10-20 at 11:42 +0200, Philippe Mathieu-Daudé wrote:
> > On 20/10/23 04:51, Andrew Jeffery wrote:
> > > On Thu, 2023-10-19 at 15:40 -0500, Glenn Miles wrote:
> > > > > The pca9552 INPUT0 and INPUT1 registers are supposed to
> > > > > hold the logical values of the LED pins.  A logical 0
> > > > > should be seen in the INPUT0/1 registers for a pin when
> > > > > its corresponding LSn bits are set to 0, which is also
> > > > > the state needed for turning on an LED in a typical
> > > > > usage scenario.  Existing code was doing the opposite
> > > > > and setting INPUT0/1 bit to a 1 when the LSn bit was
> > > > > set to 0, so this commit fixes that.
> > > > > 
> > > > > Signed-off-by: Glenn Miles 
> > > > > ---
> > > > > 
> > > > > Changes from prior version:
> > > > >  - Added comment regarding pca953X
> > > > >  - Added cover letter
> > > > > 
> > > > >   hw/misc/pca9552.c  | 18 +-
> > > > >   tests/qtest/pca9552-test.c |  6 +++---
> > > > >   2 files changed, 16 insertions(+), 8 deletions(-)
> > > > > 
> > > > > diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
> > > > > index fff19e369a..445f56a9e8 100644
> > > > > --- a/hw/misc/pca9552.c
> > > > > +++ b/hw/misc/pca9552.c
> > > > > @@ -36,7 +36,10 @@ typedef struct PCA955xClass PCA955xClass;
> > > > >   
> > > > >   DECLARE_CLASS_CHECKERS(PCA955xClass, PCA955X,
> > > > >  TYPE_PCA955X)
> > > > > -
> > > > > +/*
> > > > > + * Note:  The LED_ON and LED_OFF configuration values for the
> > > > > PCA955X
> > > > > + *chips are the reverse of the PCA953X family of
> > > > > chips.
> > > > > + */
> > > > >   #define PCA9552_LED_ON   0x0
> > > > >   #define PCA9552_LED_OFF  0x1
> > > > >   #define PCA9552_LED_PWM0 0x2
> > > > > @@ -112,13 +115,18 @@ static void
> > > > > pca955x_update_pin_input(PCA955xState *s)
> > > > >   
> > > > >   switch (config) {
> > > > >   case PCA9552_LED_ON:
> > > > > -qemu_set_irq(s->gpio[i], 1);
> > > > > -s->regs[input_reg] |= 1 << input_shift;
> > > > > -break;
> > > > > -case PCA9552_LED_OFF:
> > > > > +/* Pin is set to 0V to turn on LED */
> > > > >   qemu_set_irq(s->gpio[i], 0);
> > > > >   s->regs[input_reg] &= ~(1 << input_shift);
> > > > >   break;
> > > > > +case PCA9552_LED_OFF:
> > > > > +/*
> > > > > + * Pin is set to Hi-Z to turn off LED and
> > > > > + * pullup sets it to a logical 1.
> > > > > + */
> > > > > +qemu_set_irq(s->gpio[i], 1);
> > > > > +s->regs[input_reg] |= 1 << input_shift;
> > > > > +break;
> > > 
> > > So the witherspoon-bmc machine was a user of the PCA9552 outputs as
> > > LEDs. I guess its LEDs were in the wrong state the whole time? That
> > > looks like the only user though, and shouldn't be negatively
> > > affected.
> > 
> > Usually GPIO polarity is a machine/board property, not a device
> > one.
> > 
> > We could use the LED API (hw/misc/led.h) which initialize each
> > output with GpioPolarity.
> > 
> 
> Thanks for your comments!   This piqued my curiosity so I decided to
> run a test with the witherspoon-bmc machine.  Without my changes, I ran
> the following command to turn off LED13 on the pca9552 which I had
> previously set to "on":
> 
>   qom-set /machine/unattached/device[18] led13 off
> 
> I had GDB connected at the time with a breakpoint set on
> led_set_state() so that I could see what was happening.  Due to the
> inversion bug, I expected the pca9552 code to set the pin low and also
> set the irq low, which it did.  The connected LED's on this pca9552
> were all configured as GPIO_POLARITY_ACTIVE_LOW, so I expected that
> setting the irq state low would actually turn on the LED.  Instead it

Re: [PATCH 2/2] misc/pca9552: Let external devices set pca9552 inputs

2023-10-19 Thread Andrew Jeffery
On Thu, 2023-10-19 at 15:40 -0500, Glenn Miles wrote:
> Allow external devices to drive pca9552 input pins by adding
> input GPIO's to the model.  This allows a device to connect
> its output GPIO's to the pca9552 input GPIO's.
> 
> In order for an external device to set the state of a pca9552
> pin, the pin must first be configured for high impedance (LED
> is off).  If the pca9552 pin is configured to drive the pin low
> (LED is on), then external input will be ignored.
> 
> Here is a table describing the logical state of a pca9552 pin
> given the state being driven by the pca9552 and an external device:
> 
>PCA9552
>Configured
>State
> 
>   | Hi-Z | Low |
> --+--+-+
>   External   Hi-Z |  Hi  | Low |
>   Device--+--+-+
>   State  Low  |  Low | Low |
> --+--+-+
> 
> Signed-off-by: Glenn Miles 
> ---
> 
> Changes from previous version:
>  - Added #define's for external state values
>  - Added logic state table to commit message
>  - Added cover letter
> 
>  hw/misc/pca9552.c | 41 ++-
>  include/hw/misc/pca9552.h |  3 ++-
>  2 files changed, 38 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
> index 445f56a9e8..ed814d1f98 100644
> --- a/hw/misc/pca9552.c
> +++ b/hw/misc/pca9552.c
> @@ -44,6 +44,8 @@ DECLARE_CLASS_CHECKERS(PCA955xClass, PCA955X,
>  #define PCA9552_LED_OFF  0x1
>  #define PCA9552_LED_PWM0 0x2
>  #define PCA9552_LED_PWM1 0x3
> +#define PCA9552_PIN_LOW  0x0
> +#define PCA9552_PIN_HIZ  0x1
>  
>  static const char *led_state[] = {"on", "off", "pwm0", "pwm1"};
>  
> @@ -116,16 +118,22 @@ static void pca955x_update_pin_input(PCA955xState *s)
>  switch (config) {
>  case PCA9552_LED_ON:
>  /* Pin is set to 0V to turn on LED */
> -qemu_set_irq(s->gpio[i], 0);
> +qemu_set_irq(s->gpio_out[i], 0);

pca955x_update_pin_input() is called by the external GPIO handling path
as well as the I2C command handling path. If the I2C path sets the line
low followed by the device attached to the GPIO setting the line low
then I think each change will issue an event on the outbound GPIO. Is
that desired behaviour? Does it matter?

>  s->regs[input_reg] &= ~(1 << input_shift);
>  break;
>  case PCA9552_LED_OFF:
>  /*
>   * Pin is set to Hi-Z to turn off LED and
> - * pullup sets it to a logical 1.
> + * pullup sets it to a logical 1 unless
> + * external device drives it low.
>   */
> -qemu_set_irq(s->gpio[i], 1);
> -s->regs[input_reg] |= 1 << input_shift;
> +if (s->ext_state[i] == PCA9552_PIN_LOW) {
> +qemu_set_irq(s->gpio_out[i], 0);

Similarly here - it might be the case that both devices have pulled the
line low and now the I2C path is releasing it. Given the external
device had already pulled the line low as well should we expect an
event to occur issued here? Should it matter?

Andrew

> +s->regs[input_reg] &= ~(1 << input_shift);
> +} else {
> +qemu_set_irq(s->gpio_out[i], 1);
> +s->regs[input_reg] |= 1 << input_shift;
> +}
>  break;
>  case PCA9552_LED_PWM0:
>  case PCA9552_LED_PWM1:
> @@ -340,6 +348,7 @@ static const VMStateDescription pca9552_vmstate = {
>  VMSTATE_UINT8(len, PCA955xState),
>  VMSTATE_UINT8(pointer, PCA955xState),
>  VMSTATE_UINT8_ARRAY(regs, PCA955xState, PCA955X_NR_REGS),
> +VMSTATE_UINT8_ARRAY(ext_state, PCA955xState, PCA955X_PIN_COUNT_MAX),
>  VMSTATE_I2C_SLAVE(i2c, PCA955xState),
>  VMSTATE_END_OF_LIST()
>  }
> @@ -358,6 +367,7 @@ static void pca9552_reset(DeviceState *dev)
>  s->regs[PCA9552_LS2] = 0x55;
>  s->regs[PCA9552_LS3] = 0x55;
>  
> +memset(s->ext_state, PCA9552_PIN_HIZ, PCA955X_PIN_COUNT_MAX);
>  pca955x_update_pin_input(s);
>  
>  s->pointer = 0xFF;
> @@ -380,6 +390,26 @@ static void pca955x_initfn(Object *obj)
>  }
>  }
>  
> +static void pca955x_set_ext_state(PCA955xState *s, int pin, int level)
> +{
> +if (s->ext_state[pin] != level) {
> +uint16_t pins_status = pca955x_pins_get_status(s);
> +s->ext_state[pin] = level;
> +pca955x_update_pin_input(s);
> +pca955x_display_pins_status(s, pins_status);
> +}
> +}
> +
> +static void pca955x_gpio_in_handler(void *opaque, int pin, int level)
> +{
> +
> +PCA955xState *s = PCA955X(opaque);
> +PCA955xClass *k = PCA955X_GET_CLASS(s);
> +
> +assert((pin >= 0) && (pin < k->pin_count));
> +pca955x_set_ext_state(s, pin, level);
> +}
> +
>  static void pca955x_realize(DeviceState *dev, Error **errp)
>  {
>  PCA955xClass *k = PCA955X_GET_CLASS(dev);
> @@ -389,7 +419,8 @@ static void 

Re: [PATCH 1/2] misc/pca9552: Fix inverted input status

2023-10-19 Thread Andrew Jeffery
On Thu, 2023-10-19 at 15:40 -0500, Glenn Miles wrote:
> > The pca9552 INPUT0 and INPUT1 registers are supposed to
> > hold the logical values of the LED pins.  A logical 0
> > should be seen in the INPUT0/1 registers for a pin when
> > its corresponding LSn bits are set to 0, which is also
> > the state needed for turning on an LED in a typical
> > usage scenario.  Existing code was doing the opposite
> > and setting INPUT0/1 bit to a 1 when the LSn bit was
> > set to 0, so this commit fixes that.
> > 
> > Signed-off-by: Glenn Miles 
> > ---
> > 
> > Changes from prior version:
> > - Added comment regarding pca953X
> > - Added cover letter
> > 
> >  hw/misc/pca9552.c  | 18 +-
> >  tests/qtest/pca9552-test.c |  6 +++---
> >  2 files changed, 16 insertions(+), 8 deletions(-)
> > 
> > diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
> > index fff19e369a..445f56a9e8 100644
> > --- a/hw/misc/pca9552.c
> > +++ b/hw/misc/pca9552.c
> > @@ -36,7 +36,10 @@ typedef struct PCA955xClass PCA955xClass;
> >  
> >  DECLARE_CLASS_CHECKERS(PCA955xClass, PCA955X,
> > TYPE_PCA955X)
> > -
> > +/*
> > + * Note:  The LED_ON and LED_OFF configuration values for the PCA955X
> > + *chips are the reverse of the PCA953X family of chips.
> > + */
> >  #define PCA9552_LED_ON   0x0
> >  #define PCA9552_LED_OFF  0x1
> >  #define PCA9552_LED_PWM0 0x2
> > @@ -112,13 +115,18 @@ static void pca955x_update_pin_input(PCA955xState *s)
> >  
> >  switch (config) {
> >  case PCA9552_LED_ON:
> > -qemu_set_irq(s->gpio[i], 1);
> > -s->regs[input_reg] |= 1 << input_shift;
> > -break;
> > -case PCA9552_LED_OFF:
> > +/* Pin is set to 0V to turn on LED */
> >  qemu_set_irq(s->gpio[i], 0);
> >  s->regs[input_reg] &= ~(1 << input_shift);
> >  break;
> > +case PCA9552_LED_OFF:
> > +/*
> > + * Pin is set to Hi-Z to turn off LED and
> > + * pullup sets it to a logical 1.
> > + */
> > +    qemu_set_irq(s->gpio[i], 1);
> > +s->regs[input_reg] |= 1 << input_shift;
> > +break;

So the witherspoon-bmc machine was a user of the PCA9552 outputs as
LEDs. I guess its LEDs were in the wrong state the whole time? That
looks like the only user though, and shouldn't be negatively affected.

Reviewed-by: Andrew Jeffery 

> >  case PCA9552_LED_PWM0:
> >  case PCA9552_LED_PWM1:
> >  /* TODO */
> > diff --git a/tests/qtest/pca9552-test.c b/tests/qtest/pca9552-test.c
> > index d80ed93cd3..ccca2b3d91 100644
> > --- a/tests/qtest/pca9552-test.c
> > +++ b/tests/qtest/pca9552-test.c
> > @@ -60,7 +60,7 @@ static void send_and_receive(void *obj, void *data, 
> > QGuestAllocator *alloc)
> >  g_assert_cmphex(value, ==, 0x55);
> >  
> >  value = i2c_get8(i2cdev, PCA9552_INPUT0);
> > -g_assert_cmphex(value, ==, 0x0);
> > +g_assert_cmphex(value, ==, 0xFF);
> >  
> >  pca9552_init(i2cdev);
> >  
> > @@ -68,13 +68,13 @@ static void send_and_receive(void *obj, void *data, 
> > QGuestAllocator *alloc)
> >  g_assert_cmphex(value, ==, 0x54);
> >  
> >  value = i2c_get8(i2cdev, PCA9552_INPUT0);
> > -g_assert_cmphex(value, ==, 0x01);
> > +g_assert_cmphex(value, ==, 0xFE);
> >  
> >  value = i2c_get8(i2cdev, PCA9552_LS3);
> >  g_assert_cmphex(value, ==, 0x54);
> >  
> >  value = i2c_get8(i2cdev, PCA9552_INPUT1);
> > -g_assert_cmphex(value, ==, 0x10);
> > +g_assert_cmphex(value, ==, 0xEF);
> >  }
> >  
> >  static void pca9552_register_nodes(void)





Re: [Qemu-devel] [PATCH 08/19] aspeed/timer: Fix behaviour running Linux

2023-09-25 Thread Andrew Jeffery



On Mon, 25 Sep 2023, at 18:50, Cédric Le Goater wrote:
> On 9/25/23 09:54, Andrew Jeffery wrote:
>> 
>> 
>> On Fri, 22 Sep 2023, at 22:51, Cédric Le Goater wrote:
>>> Joel, Andrew,
>>>
>>> On 5/25/19 17:12, Cédric Le Goater wrote:
>>>> From: Joel Stanley 
>>>>
>>>> The Linux kernel driver was updated in commit 4451d3f59f2a
>>>> ("clocksource/drivers/fttmr010: Fix set_next_event handler) to fix an
>>>> issue observed on hardware:
>>>>
>>>>> RELOAD register is loaded into COUNT register when the aspeed timer
>>>>> is enabled, which means the next event may be delayed because timer
>>>>> interrupt won't be generated until <0x - current_count +
>>>>> cycles>.
>>>>
>>>> When running under Qemu, the system appeared "laggy". The guest is now
>>>> scheduling timer events too regularly, starving the host of CPU time.
>>>>
>>>> This patch modifies the timer model to attempt to schedule the timer
>>>> expiry as the guest requests, but if we have missed the deadline we
>>>> re interrupt and try again, which allows the guest to catch up.
>>>>
>>>> Provides expected behaviour with old and new guest code.
>>>>
>>>> Fixes: c04bd47db6b9 ("hw/timer: Add ASPEED timer device model")
>>>> Signed-off-by: Joel Stanley 
>>>> [clg: - merged a fix from Andrew Jeffery 
>>>>   "Fire interrupt on failure to meet deadline"
>>>>   
>>>> https://lists.ozlabs.org/pipermail/openbmc/2019-January/014641.html
>>>> - adapted commit log
>>>> - checkpatch fixes ]
>>>> Signed-off-by: Cédric Le Goater 
>>>> ---
>>>>hw/timer/aspeed_timer.c | 59 ++---
>>>>1 file changed, 31 insertions(+), 28 deletions(-)
>>>>
>>>> diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
>>>> index 5c786e512815..9ffd8e09f670 100644
>>>> --- a/hw/timer/aspeed_timer.c
>>>> +++ b/hw/timer/aspeed_timer.c
>>>> @@ -109,37 +109,40 @@ static inline uint64_t calculate_time(struct 
>>>> AspeedTimer *t, uint32_t ticks)
>>>>
>>>>static uint64_t calculate_next(struct AspeedTimer *t)
>>>>{
>>>> -uint64_t next = 0;
>>>> -uint32_t rate = calculate_rate(t);
>>>> +uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>>>> +uint64_t next;
>>>>
>>>> -while (!next) {
>>>> -/* We don't know the relationship between the values in the match
>>>> - * registers, so sort using MAX/MIN/zero. We sort in that order 
>>>> as the
>>>> - * timer counts down to zero. */
>>>> -uint64_t seq[] = {
>>>> -calculate_time(t, MAX(t->match[0], t->match[1])),
>>>> -calculate_time(t, MIN(t->match[0], t->match[1])),
>>>> -calculate_time(t, 0),
>>>> -};
>>>> -uint64_t reload_ns;
>>>> -uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>>>> -
>>>> -if (now < seq[0]) {
>>>> -next = seq[0];
>>>> -} else if (now < seq[1]) {
>>>> -next = seq[1];
>>>> -} else if (now < seq[2]) {
>>>> -next = seq[2];
>>>> -} else if (t->reload) {
>>>> -reload_ns = muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate);
>>>> -t->start = now - ((now - t->start) % reload_ns);
>>>> -} else {
>>>> -/* no reload value, return 0 */
>>>> -break;
>>>> -}
>>>> +/*
>>>> + * We don't know the relationship between the values in the match
>>>> + * registers, so sort using MAX/MIN/zero. We sort in that order as
>>>> + * the timer counts down to zero.
>>>> + */
>>>> +
>>>> +next = calculate_time(t, MAX(t->match[0], t->match[1]));
>>>> +if (now < next) {
>>>> +return next;
>>>> +}
>>>> +
>>>> +next = calculate_time(t, MIN(t->match[0], t->match[1]));
>>>> +if (now < next) {
>>>> +return next;
>>>> +}
>>>> +
>>>> +next = calculate_time(t, 0);
>>>> +if (now < next) {
>>>> +return next;
>>>> +}
>>>> +
>>>> +/* We've missed all deadlines, fire interrupt and try again */
>>>> +timer_del(>timer);
>>>> +
>>>> +if (timer_overflow_interrupt(t)) {
>>>> +t->level = !t->level;
>>>> +qemu_set_irq(t->irq, t->level);
>>>>}
>>>>
>>>> -return next;
>>>> +t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>>>> +return calculate_time(t, MAX(MAX(t->match[0], t->match[1]), 0));
>>>
>>> This MAX(MAX(x, y), 0) looks strange to me. Would you remember where it 
>>> comes
>>> from ? Thanks,
>> 
>> The inner MAX() deals with the lack of ordering constraints between the 
>> match values. I think the outer MAX() is redundant. We should probably 
>> remove it. The match member is type uint32_t so it can't be negative. You 
>> did steal that from an RFC patch :D
>
> I did ! Fixed there :
>
>
> https://patchwork.ozlabs.org/project/qemu-devel/patch/20230922155924.1172019-5-...@kaod.org/
>

Thanks. That one might be further down in my review queue 

Andrew



Re: [PATCH] MAINTAINERS: aspeed: Update Andrew's email address

2023-09-25 Thread Andrew Jeffery



On Mon, 25 Sep 2023, at 17:28, Cédric Le Goater wrote:
> On 9/25/23 08:22, Andrew Jeffery wrote:
>> I've changed employers, have company email that deals with patch-based
>> workflows without too much of a headache, and am trying to steer some
>> content out of my personal mail.
>> 
>> Signed-off-by: Andrew Jeffery 
>> ---
>> 
>> Hi Cédric, do you mind including this in your Aspeed queue?
>
> Sure. It's on aspeed-8.2 for now. I will send a PR when I have more
> material for QEMU 8.2
>

Thanks!



Re: [Qemu-devel] [PATCH 08/19] aspeed/timer: Fix behaviour running Linux

2023-09-25 Thread Andrew Jeffery



On Fri, 22 Sep 2023, at 22:51, Cédric Le Goater wrote:
> Joel, Andrew,
>
> On 5/25/19 17:12, Cédric Le Goater wrote:
>> From: Joel Stanley 
>> 
>> The Linux kernel driver was updated in commit 4451d3f59f2a
>> ("clocksource/drivers/fttmr010: Fix set_next_event handler) to fix an
>> issue observed on hardware:
>> 
>>   > RELOAD register is loaded into COUNT register when the aspeed timer
>>   > is enabled, which means the next event may be delayed because timer
>>   > interrupt won't be generated until <0x - current_count +
>>   > cycles>.
>> 
>> When running under Qemu, the system appeared "laggy". The guest is now
>> scheduling timer events too regularly, starving the host of CPU time.
>> 
>> This patch modifies the timer model to attempt to schedule the timer
>> expiry as the guest requests, but if we have missed the deadline we
>> re interrupt and try again, which allows the guest to catch up.
>> 
>> Provides expected behaviour with old and new guest code.
>> 
>> Fixes: c04bd47db6b9 ("hw/timer: Add ASPEED timer device model")
>> Signed-off-by: Joel Stanley 
>> [clg: - merged a fix from Andrew Jeffery 
>>  "Fire interrupt on failure to meet deadline"
>>  https://lists.ozlabs.org/pipermail/openbmc/2019-January/014641.html
>>- adapted commit log
>>- checkpatch fixes ]
>> Signed-off-by: Cédric Le Goater 
>> ---
>>   hw/timer/aspeed_timer.c | 59 ++---
>>   1 file changed, 31 insertions(+), 28 deletions(-)
>> 
>> diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
>> index 5c786e512815..9ffd8e09f670 100644
>> --- a/hw/timer/aspeed_timer.c
>> +++ b/hw/timer/aspeed_timer.c
>> @@ -109,37 +109,40 @@ static inline uint64_t calculate_time(struct 
>> AspeedTimer *t, uint32_t ticks)
>>   
>>   static uint64_t calculate_next(struct AspeedTimer *t)
>>   {
>> -uint64_t next = 0;
>> -uint32_t rate = calculate_rate(t);
>> +uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>> +uint64_t next;
>>   
>> -while (!next) {
>> -/* We don't know the relationship between the values in the match
>> - * registers, so sort using MAX/MIN/zero. We sort in that order as 
>> the
>> - * timer counts down to zero. */
>> -uint64_t seq[] = {
>> -calculate_time(t, MAX(t->match[0], t->match[1])),
>> -calculate_time(t, MIN(t->match[0], t->match[1])),
>> -calculate_time(t, 0),
>> -};
>> -uint64_t reload_ns;
>> -uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>> -
>> -if (now < seq[0]) {
>> -next = seq[0];
>> -} else if (now < seq[1]) {
>> -next = seq[1];
>> -} else if (now < seq[2]) {
>> -next = seq[2];
>> -} else if (t->reload) {
>> -reload_ns = muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate);
>> -t->start = now - ((now - t->start) % reload_ns);
>> -} else {
>> -/* no reload value, return 0 */
>> -break;
>> -}
>> +/*
>> + * We don't know the relationship between the values in the match
>> + * registers, so sort using MAX/MIN/zero. We sort in that order as
>> + * the timer counts down to zero.
>> + */
>> +
>> +next = calculate_time(t, MAX(t->match[0], t->match[1]));
>> +if (now < next) {
>> +return next;
>> +}
>> +
>> +next = calculate_time(t, MIN(t->match[0], t->match[1]));
>> +if (now < next) {
>> +return next;
>> +}
>> +
>> +next = calculate_time(t, 0);
>> +if (now < next) {
>> +return next;
>> +}
>> +
>> +/* We've missed all deadlines, fire interrupt and try again */
>> +timer_del(>timer);
>> +
>> +if (timer_overflow_interrupt(t)) {
>> +t->level = !t->level;
>> +qemu_set_irq(t->irq, t->level);
>>   }
>>   
>> -return next;
>> +t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>> +return calculate_time(t, MAX(MAX(t->match[0], t->match[1]), 0));
>
> This MAX(MAX(x, y), 0) looks strange to me. Would you remember where it comes
> from ? Thanks,

The inner MAX() deals with the lack of ordering constraints between the match 
values. I think the outer MAX() is redundant. We should probably remove it. The 
match member is type uint32_t so it can't be negative. You did steal that from 
an RFC patch :D

Andrew



Re: [PATCH 3/4] aspeed/i3c: Rename variable shadowing a local

2023-09-25 Thread Andrew Jeffery



On Sat, 23 Sep 2023, at 03:58, Philippe Mathieu-Daudé wrote:
> On 22/9/23 17:59, Cédric Le Goater wrote:
>> to fix warning :
>> 
>>../hw/i3c/aspeed_i3c.c: In function ‘aspeed_i3c_realize’:
>>../hw/i3c/aspeed_i3c.c:1959:17: warning: declaration of ‘dev’ shadows a 
>> parameter [-Wshadow=local]
>> 1959 | Object *dev = OBJECT(>devices[i]);
>>  | ^~~
>>../hw/i3c/aspeed_i3c.c:1942:45: note: shadowed declaration is here
>> 1942 | static void aspeed_i3c_realize(DeviceState *dev, Error **errp)
>>  |~^~~
>> 
>> Signed-off-by: Cédric Le Goater 
>> ---
>>   hw/misc/aspeed_i3c.c | 6 +++---
>>   1 file changed, 3 insertions(+), 3 deletions(-)
>> 
>> diff --git a/hw/misc/aspeed_i3c.c b/hw/misc/aspeed_i3c.c
>> index f54f5da522b3..d1ff61767167 100644
>> --- a/hw/misc/aspeed_i3c.c
>> +++ b/hw/misc/aspeed_i3c.c
>> @@ -296,13 +296,13 @@ static void aspeed_i3c_realize(DeviceState *dev, Error 
>> **errp)
>
> Alternatively:
>
> -- >8 --
>
> -static void aspeed_i3c_realize(DeviceState *dev, Error **errp)
> +static void aspeed_i3c_realize(DeviceState *ctrl, Error **errp)
>   {
>   int i;
> -AspeedI3CState *s = ASPEED_I3C(dev);
> -SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> +AspeedI3CState *s = ASPEED_I3C(ctrl);
> +SysBusDevice *sbd = SYS_BUS_DEVICE(ctrl);

Hmm, I feel like `dev` isn't an unreasonable or unusual name for the formal 
parameter? Switching to `ctrl` isn't my immediate preference.

>
> ---
>
>>   memory_region_add_subregion(>iomem_container, 0x0, >iomem);
>>   
>>   for (i = 0; i < ASPEED_I3C_NR_DEVICES; ++i) {
>> -Object *dev = OBJECT(>devices[i]);
>> +Object *i3c_dev = OBJECT(>devices[i]);

Maybe `s/i3c_dev/subdev`? I dunno. That bikeshed isn't gonna get painted on its 
own.

Reviewed-by: Andrew Jeffery 

>>   
>> -if (!object_property_set_uint(dev, "device-id", i, errp)) {
>> +if (!object_property_set_uint(i3c_dev, "device-id", i, errp)) {
>>   return;
>>   }
>>   
>> -if (!sysbus_realize(SYS_BUS_DEVICE(dev), errp)) {
>> +if (!sysbus_realize(SYS_BUS_DEVICE(i3c_dev), errp)) {
>>   return;
>>   }
>>   
>
> Reviewed-by: Philippe Mathieu-Daudé 



[PATCH] MAINTAINERS: aspeed: Update Andrew's email address

2023-09-25 Thread Andrew Jeffery
I've changed employers, have company email that deals with patch-based
workflows without too much of a headache, and am trying to steer some
content out of my personal mail.

Signed-off-by: Andrew Jeffery 
---

Hi Cédric, do you mind including this in your Aspeed queue?

 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 355b1960ce46..b142c09628b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1108,7 +1108,7 @@ F: docs/system/arm/emcraft-sf2.rst
 ASPEED BMCs
 M: Cédric Le Goater 
 M: Peter Maydell 
-R: Andrew Jeffery 
+R: Andrew Jeffery 
 R: Joel Stanley 
 L: qemu-...@nongnu.org
 S: Maintained
-- 
2.39.2




Re: [PATCH v6 1/3] hw/i2c: add smbus pec utility function

2023-09-21 Thread Andrew Jeffery
On Thu, 2023-09-14 at 11:53 +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Add i2c_smbus_pec() to calculate the SMBus Packet Error Code for a
> message.
> 
> Reviewed-by: Jonathan Cameron 
> Signed-off-by: Klaus Jensen 

It at least looks a lot like the linux implementation :)

Reviewed-by: Andrew Jeffery 

> ---
>  hw/i2c/smbus_master.c | 26 ++
>  include/hw/i2c/smbus_master.h |  2 ++
>  2 files changed, 28 insertions(+)
> 
> diff --git a/hw/i2c/smbus_master.c b/hw/i2c/smbus_master.c
> index 6a53c34e70b7..01a8e4700222 100644
> --- a/hw/i2c/smbus_master.c
> +++ b/hw/i2c/smbus_master.c
> @@ -15,6 +15,32 @@
>  #include "hw/i2c/i2c.h"
>  #include "hw/i2c/smbus_master.h"
>  
> +static uint8_t crc8(uint16_t data)
> +{
> +int i;
> +
> +for (i = 0; i < 8; i++) {
> +if (data & 0x8000) {
> +data ^= 0x1070U << 3;
> +}
> +
> +data <<= 1;
> +}
> +
> +return (uint8_t)(data >> 8);
> +}
> +
> +uint8_t i2c_smbus_pec(uint8_t crc, uint8_t *buf, size_t len)
> +{
> +int i;
> +
> +for (i = 0; i < len; i++) {
> +crc = crc8((crc ^ buf[i]) << 8);
> +}
> +
> +return crc;
> +}
> +
>  /* Master device commands.  */
>  int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
>  {
> diff --git a/include/hw/i2c/smbus_master.h b/include/hw/i2c/smbus_master.h
> index bb13bc423c22..d90f81767d86 100644
> --- a/include/hw/i2c/smbus_master.h
> +++ b/include/hw/i2c/smbus_master.h
> @@ -27,6 +27,8 @@
>  
>  #include "hw/i2c/i2c.h"
>  
> +uint8_t i2c_smbus_pec(uint8_t crc, uint8_t *buf, size_t len);
> +
>  /* Master device commands.  */
>  int smbus_quick_command(I2CBus *bus, uint8_t addr, int read);
>  int smbus_receive_byte(I2CBus *bus, uint8_t addr);
> 




Re: [PATCH v6 2/3] hw/i2c: add mctp core

2023-09-21 Thread Andrew Jeffery
On Thu, 2023-09-14 at 11:53 +0200, Klaus Jensen wrote:
> From: Klaus Jensen 
> 
> Add an abstract MCTP over I2C endpoint model. This implements MCTP
> control message handling as well as handling the actual I2C transport
> (packetization).
> 
> Devices are intended to derive from this and implement the class
> methods.
> 
> Parts of this implementation is inspired by code[1] previously posted by
> Jonathan Cameron.
> 
> Squashed a fix[2] from Matt Johnston.
> 
>   [1]: 
> https://lore.kernel.org/qemu-devel/20220520170128.4436-1-jonathan.came...@huawei.com/
>   [2]: 
> https://lore.kernel.org/qemu-devel/20221121080445.ga29...@codeconstruct.com.au/
> 
> Tested-by: Jonathan Cameron 
> Reviewed-by: Jonathan Cameron 
> Signed-off-by: Klaus Jensen 

Nice!

Reviewed-by: Andrew Jeffery 



Re: [PATCH v6 3/3] hw/nvme: add nvme management interface model

2023-09-21 Thread Andrew Jeffery
 +switch (request->opc) {
> +case NMI_CMD_READ_NMI_DS:
> +nmi_handle_mi_read_nmi_ds(nmi, request);
> +break;
> +
> +case NMI_CMD_CONFIGURATION_GET:
> +nmi_handle_mi_config_get(nmi, request);
> +break;
> +
> +default:
> +nmi_set_parameter_error(nmi, 0x0, 0x0);
> +fprintf(stderr, "nmi command 0x%x not handled\n", request->opc);
> +
> +break;
> +}
> +}
> +
> +static void nmi_reset(MCTPI2CEndpoint *mctp)
> +{
> +NMIDevice *nmi = NMI_I2C_DEVICE(mctp);
> +nmi->len = 0;
> +}
> +
> +static void nmi_handle(MCTPI2CEndpoint *mctp)
> +{
> +NMIDevice *nmi = NMI_I2C_DEVICE(mctp);
> +NMIMessage *msg = (NMIMessage *)nmi->buffer;
> +uint32_t crc;
> +uint8_t nmimt;
> +
> +const uint8_t buf[] = {
> +msg->mctpd,
> +FIELD_DP8(msg->nmp, NMI_NMP, ROR, 1),
> +0x0, 0x0,
> +};
> +
> +if (FIELD_EX8(msg->mctpd, NMI_MCTPD, MT) != NMI_MCTPD_MT_NMI) {
> +goto drop;
> +}
> +
> +if (FIELD_EX8(msg->mctpd, NMI_MCTPD, IC) != NMI_MCTPD_IC_ENABLED) {
> +goto drop;
> +}
> +
> +nmi->pos = 0;
> +nmi_scratch_append(nmi, buf, sizeof(buf));
> +
> +nmimt = FIELD_EX8(msg->nmp, NMI_NMP, NMIMT);
> +
> +trace_nmi_handle_msg(nmimt);
> +
> +switch (nmimt) {
> +case NMI_NMP_NMIMT_NVME_MI:
> +nmi_handle_mi(nmi, msg);
> +break;
> +
> +default:
> +fprintf(stderr, "nmi message type 0x%x not handled\n", nmimt);
> +
> +nmi_set_error(nmi, 0x3);

0x3 is Invalid Command Opcode? I feel it would be be helpful to give it
a name.

Otherwise, this looks good to me. I realise I haven't contributed much
upstream recently, but FWIW:

Reviewed-by: Andrew Jeffery 

> +
> +break;
> +}
> +
> +crc = crc32c(0x, nmi->scratch, nmi->pos);
> +nmi_scratch_append(nmi, , sizeof(crc));
> +
> +nmi->len = nmi->pos;
> +nmi->pos = 0;
> +
> +i2c_mctp_schedule_send(mctp);
> +
> +return;
> +
> +drop:
> +nmi_reset(mctp);
> +}
> +
> +static size_t nmi_get_buf(MCTPI2CEndpoint *mctp, const uint8_t **buf,
> +  size_t maxlen, uint8_t *mctp_flags)
> +{
> +NMIDevice *nmi = NMI_I2C_DEVICE(mctp);
> +size_t len;
> +
> +len = MIN(maxlen, nmi->len - nmi->pos);
> +
> +if (len == 0) {
> +return 0;
> +}
> +
> +if (nmi->pos == 0) {
> +*mctp_flags = FIELD_DP8(*mctp_flags, MCTP_H_FLAGS, SOM, 1);
> +}
> +
> +*buf = nmi->scratch + nmi->pos;
> +nmi->pos += len;
> +
> +if (nmi->pos == nmi->len) {
> +*mctp_flags = FIELD_DP8(*mctp_flags, MCTP_H_FLAGS, EOM, 1);
> +
> +nmi->pos = nmi->len = 0;
> +}
> +
> +return len;
> +}
> +
> +static int nmi_put_buf(MCTPI2CEndpoint *mctp, uint8_t *buf, size_t len)
> +{
> +NMIDevice *nmi = NMI_I2C_DEVICE(mctp);
> +
> +if (nmi->len + len > NMI_MAX_MESSAGE_LENGTH) {
> +return -1;
> +}
> +
> +memcpy(nmi->buffer + nmi->len, buf, len);
> +nmi->len += len;
> +
> +return 0;
> +}
> +
> +static size_t nmi_get_types(MCTPI2CEndpoint *mctp, const uint8_t **data)
> +{
> +/**
> + * DSP0236 1.3.0, Table 19.
> + *
> + * This only includes message types that are supported *in addition* to 
> the
> + * MCTP control message type.
> + */
> +static const uint8_t buf[] = {
> +0x0,/* success */
> +0x1,/* number of message types in list (supported) */
> +NMI_MCTPD_MT_NMI,
> +};
> +
> +*data = buf;
> +
> +return sizeof(buf);
> +}
> +
> +static void nvme_mi_class_init(ObjectClass *oc, void *data)
> +{
> +MCTPI2CEndpointClass *mc = MCTP_I2C_ENDPOINT_CLASS(oc);
> +
> +mc->get_types = nmi_get_types;
> +
> +mc->get_buf = nmi_get_buf;
> +mc->put_buf = nmi_put_buf;
> +
> +mc->handle = nmi_handle;
> +mc->reset = nmi_reset;
> +}
> +
> +static const TypeInfo nvme_mi = {
> +.name = TYPE_NMI_I2C_DEVICE,
> +.parent = TYPE_MCTP_I2C_ENDPOINT,
> +.instance_size = sizeof(NMIDevice),
> +.class_init = nvme_mi_class_init,
> +};
> +
> +static void register_types(void)
> +{
> +type_register_static(_mi);
> +}
> +
> +type_init(register_types);
> diff --git a/hw/nvme/trace-events b/hw/nvme/trace-events
> index 3a67680c6ad1..41e2c540dcf2 100644
> --- a/hw/nvme/trace-events
> +++ b/hw/nvme/trace-events
> @@ -216,3 +216,9 @@ pci_nvme_ub_db_wr_invalid_sq(uint32_t qid) "submission 
> queue doorbell write for
>  pci_nvme_ub_db_wr_invalid_sqtail(uint32_t qid, uint16_t new_tail) 
> "submission queue doorbell write value beyond queue size, sqid=%"PRIu32", 
> new_head=%"PRIu16", ignoring"
>  pci_nvme_ub_unknown_css_value(void) "unknown value in cc.css field"
>  pci_nvme_ub_too_many_mappings(void) "too many prp/sgl mappings"
> +
> +# nmi-i2c
> +nmi_handle_mi_read_nmi_ds(uint8_t dtyp) "dtyp 0x%"PRIx8""
> +nmi_handle_mi_config_get(uint8_t identifier) "identifier 0x%"PRIx8""
> +nmi_handle_mi(uint8_t opc) "opc 0x%"PRIx8""
> +nmi_handle_msg(uint8_t nmint) "nmint 0x%"PRIx8""
> 




[PATCH] eeprom_at24c: Model 8-bit data addressing for 16-bit devices

2023-09-20 Thread Andrew Jeffery
It appears some (many?) EEPROMs that implement 16-bit data addressing
will accept an 8-bit address and clock out non-uniform data for the
read. This behaviour is exploited by an EEPROM detection routine in part
of OpenBMC userspace with a reasonably broad user base:

https://github.com/openbmc/entity-manager/blob/0422a24bb6033605ce75479f675fedc76abb1167/src/fru_device.cpp#L197-L229

The diversity of the set of EEPROMs that it operates against is unclear,
but this code has been around for a while now.

Separately, The NVM Express Management Interface Specification dictates
the provided behaviour in section 8.2 Vital Product Data:

> If only one byte of the Command Offset is provided by the Management
> Controller, then the least significant byte of the internal offset
> shall be set to that value and the most-significant byte of the
> internal offset shall be cleared to 0h

https://nvmexpress.org/wp-content/uploads/NVM-Express-Management-Interface-Specification-1.2c-2022.10.06-Ratified.pdf

This change makes it possible to expose NVMe VPD in a manner that can be
dynamically detected by OpenBMC.

Signed-off-by: Andrew Jeffery 
---
 hw/nvram/eeprom_at24c.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 613c4929e327..64a61cc0e468 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -98,12 +98,20 @@ uint8_t at24c_eeprom_recv(I2CSlave *s)
 EEPROMState *ee = AT24C_EE(s);
 uint8_t ret;
 
-/*
- * 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;
+/*
+ * Provide behaviour that aligns with NVMe MI 1.2c, section 8.2.
+ *
+ * 
https://nvmexpress.org/wp-content/uploads/NVM-Express-Management-Interface-Specification-1.2c-2022.10.06-Ratified.pdf
+ *
+ * Otherwise, the clocked-out data is meaningless anyway, and so 
reading
+ * off memory is as good a behaviour as anything. This also happens to
+ * help the address-width detection heuristic in OpenBMC's userspace.
+ *
+ * 
https://github.com/openbmc/entity-manager/blob/0422a24bb6033605ce75479f675fedc76abb1167/src/fru_device.cpp#L197-L229
+ */
+ee->haveaddr = ee->asize;
+ee->cur %= ee->rsize;
 }
 
 ret = ee->mem[ee->cur];
-- 
2.39.2




Re: [PATCH v5 3/3] hw/nvme: add nvme management interface model

2023-09-14 Thread Andrew Jeffery
Hi Klaus,

On Thu, 2023-09-14 at 08:51 +0200, Klaus Jensen wrote:
> On Sep 12 13:50, Andrew Jeffery wrote:
> > Hi Klaus,
> > 
> > On Tue, 2023-09-05 at 10:38 +0200, Klaus Jensen wrote:
> > > > 
> > > > +static void nmi_handle_mi_config_get(NMIDevice *nmi, NMIRequest
> > > > *request)
> > > > +{
> > > > +    uint32_t dw0 = le32_to_cpu(request->dw0);
> > > > +    uint8_t identifier = FIELD_EX32(dw0,
> > > > NMI_CMD_CONFIGURATION_GET_DW0,
> > > > +    IDENTIFIER);
> > > > +    const uint8_t *buf;
> > > > +
> > > > +    static const uint8_t smbus_freq[4] = {
> > > > +    0x00,   /* success */
> > > > +    0x01, 0x00, 0x00,   /* 100 kHz */
> > > > +    };
> > > > +
> > > > +    static const uint8_t mtu[4] = {
> > > > +    0x00,   /* success */
> > > > +    0x40, 0x00, /* 64 */
> > > > +    0x00,   /* reserved */
> > > > +    };
> > > > +
> > > > +    trace_nmi_handle_mi_config_get(identifier);
> > > > +
> > > > +    switch (identifier) {
> > > > +    case NMI_CMD_CONFIGURATION_GET_SMBUS_FREQ:
> > > > +    buf = smbus_freq;
> > > > +    break;
> > > > +
> > > > +    case NMI_CMD_CONFIGURATION_GET_MCTP_TRANSMISSION_UNIT:
> > > > +    buf = mtu;
> > > > +    break;
> > > > +
> > > > +    default:
> > > > +    nmi_set_parameter_error(nmi, 0x0, offsetof(NMIRequest,
> > > > dw0));
> > > > +    return;
> > > > +    }
> > > > +
> > > > +    nmi_scratch_append(nmi, buf, sizeof(buf));
> > > > +}
> > 
> > When I tried to build this patch I got:
> > 
> > ```
> > In file included from /usr/include/string.h:535,
> >  from 
> > /home/andrew/src/qemu.org/qemu/include/qemu/osdep.h:112,
> >  from ../hw/nvme/nmi-i2c.c:12:
> > In function ‘memcpy’,
> > inlined from ‘nmi_scratch_append’ at ../hw/nvme/nmi-i2c.c:80:5,
> > inlined from ‘nmi_handle_mi_config_get’ at ../hw/nvme/nmi-i2c.c:246:5,
> > inlined from ‘nmi_handle_mi’ at ../hw/nvme/nmi-i2c.c:266:9,
> > inlined from ‘nmi_handle’ at ../hw/nvme/nmi-i2c.c:313:9:
> > /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:10: error: 
> > ‘__builtin_memcpy’ forming offset [4, 7] is out of the bounds [0, 4] 
> > [-Werror=array-bounds=]
> >29 |   return __builtin___memcpy_chk (__dest, __src, __len,
> >   |  ^
> >30 |  __glibc_objsize0 (__dest));
> >   |  ~~
> > ```
> > 
> > It wasn't clear initially from the error that the source of the problem
> > was the size associated with the source buffer, especially as there is
> > some pointer arithmetic being done to derive `__dest`.
> > 
> > Anyway, what we're trying to express is that the size to copy from buf
> > is the size of the array pointed to by buf. However, buf is declared as
> > a pointer to uint8_t, which loses the length information. To fix that I
> > think we need:
> > 
> > - const uint8_t *buf;
> > + const uint8_t (*buf)[4];
> > 
> > and then:
> > 
> > - nmi_scratch_append(nmi, buf, sizeof(buf));
> > + nmi_scratch_append(nmi, buf, sizeof(*buf));
> > 
> > Andrew
> > 
> 
> Hi Andrew,
> 
> Nice (and important) catch! Just curious, are you massaging QEMU's build
> system into adding additional checks or how did your compiler catch
> this?

No tricks to be honest, I just applied your patches on top of
9ef497755afc ("Merge tag 'pull-vfio-20230911' of
https://github.com/legoater/qemu into staging") using `b4 shazam ...`.

I'm building on Debian Bookworm:

$ gcc --version | head -n1
gcc (Debian 12.2.0-14) 12.2.0

Andrew



Re: [PATCH v5 3/3] hw/nvme: add nvme management interface model

2023-09-12 Thread Andrew Jeffery
Hi Klaus,

On Tue, 2023-09-05 at 10:38 +0200, Klaus Jensen wrote:
> > 
> > +static void nmi_handle_mi_config_get(NMIDevice *nmi, NMIRequest
> > *request)
> > +{
> > +    uint32_t dw0 = le32_to_cpu(request->dw0);
> > +    uint8_t identifier = FIELD_EX32(dw0,
> > NMI_CMD_CONFIGURATION_GET_DW0,
> > +    IDENTIFIER);
> > +    const uint8_t *buf;
> > +
> > +    static const uint8_t smbus_freq[4] = {
> > +    0x00,   /* success */
> > +    0x01, 0x00, 0x00,   /* 100 kHz */
> > +    };
> > +
> > +    static const uint8_t mtu[4] = {
> > +    0x00,   /* success */
> > +    0x40, 0x00, /* 64 */
> > +    0x00,   /* reserved */
> > +    };
> > +
> > +    trace_nmi_handle_mi_config_get(identifier);
> > +
> > +    switch (identifier) {
> > +    case NMI_CMD_CONFIGURATION_GET_SMBUS_FREQ:
> > +    buf = smbus_freq;
> > +    break;
> > +
> > +    case NMI_CMD_CONFIGURATION_GET_MCTP_TRANSMISSION_UNIT:
> > +    buf = mtu;
> > +    break;
> > +
> > +    default:
> > +    nmi_set_parameter_error(nmi, 0x0, offsetof(NMIRequest,
> > dw0));
> > +    return;
> > +    }
> > +
> > +    nmi_scratch_append(nmi, buf, sizeof(buf));
> > +}

When I tried to build this patch I got:

```
In file included from /usr/include/string.h:535,
 from /home/andrew/src/qemu.org/qemu/include/qemu/osdep.h:112,
 from ../hw/nvme/nmi-i2c.c:12:
In function ‘memcpy’,
inlined from ‘nmi_scratch_append’ at ../hw/nvme/nmi-i2c.c:80:5,
inlined from ‘nmi_handle_mi_config_get’ at ../hw/nvme/nmi-i2c.c:246:5,
inlined from ‘nmi_handle_mi’ at ../hw/nvme/nmi-i2c.c:266:9,
inlined from ‘nmi_handle’ at ../hw/nvme/nmi-i2c.c:313:9:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:10: error: 
‘__builtin_memcpy’ forming offset [4, 7] is out of the bounds [0, 4] 
[-Werror=array-bounds=]
   29 |   return __builtin___memcpy_chk (__dest, __src, __len,
  |  ^
   30 |  __glibc_objsize0 (__dest));
  |  ~~
```

It wasn't clear initially from the error that the source of the problem
was the size associated with the source buffer, especially as there is
some pointer arithmetic being done to derive `__dest`.

Anyway, what we're trying to express is that the size to copy from buf
is the size of the array pointed to by buf. However, buf is declared as
a pointer to uint8_t, which loses the length information. To fix that I
think we need:

- const uint8_t *buf;
+ const uint8_t (*buf)[4];

and then:

- nmi_scratch_append(nmi, buf, sizeof(buf));
+ nmi_scratch_append(nmi, buf, sizeof(*buf));

Andrew




Re: [PATCH v3 1/1] hw/arm/aspeed:Add vpd data for Rainier machine

2023-05-24 Thread Andrew Jeffery



On Wed, 24 May 2023, at 17:14, Joel Stanley wrote:
> On Wed, 24 May 2023 at 06:38, Cédric Le Goater  wrote:
>>
>> But, I also got this :
>>
>>root@p10bmc:~# [   91.656331] watchdog: watchdog0: watchdog did not stop!
>>[   91.734858] systemd-shutdown[1]: Using hardware watchdog 'aspeed_wdt', 
>> version 0, device /dev/watchdog0
>>[   91.735766] systemd-shutdown[1]: Watchdog running with a timeout of 
>> 1min.
>>[   91.987363] systemd-shutdown[1]: Syncing filesystems and block devices.
>>[   93.471897] systemd-shutdown[1]: Sending SIGTERM to remaining 
>> processes...
>>
>> and the machine rebooted.
>>
>> Joel had the same problem :
>>
>>https://github.com/openbmc/qemu/issues/39
>>
>> Is it unrelated ? I haven't started a rainier in 2 years at least so I can
>> not tell.
>
> I don't think it's related to Ninad's patches.
>
> I am able to reproduce the issue on my old Skylake x86 machine, but it
> doesn't happen on my M1 mac mini.
>
> I suspect the emulation is moving too slowly, but the host's wall
> clock is still ticking, so all of a sudden the BMC finds out that time
> has passed an the watchdog bites. I could be wrong.

Yeah, I also suspect this is occurring. In some cases we see output
like:

```
[  295.474921] hrtimer: interrupt took 411679950 ns
Watchdog timer 0 expired.
```

This suggests that we've exhausted the three iterations of the hrtimer
callback list from the hrtimer interrupt[1]. Too much stuff happening
for the time-keeping we have.

[1]: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/time/hrtimer.c?h=v6.3#n1869

However, regarding Cédric's log above, a reboot is expected on the first
boot of a fresh image when there's valid VPD available. For the first
boot of a fresh image we configure the kernel with a minimal devicetree
that allows us to read the VPD data. This determines the system we're
actually on and configures an appropriate devicetree for subsequent
boots. We then reboot to pick up the new devicetree.

The devicetree to use is stored in the u-boot environment (in
`fitconfig`).

Andrew



[PATCH 0/2] linux-user: Clarify error on failure to map guest address space

2023-03-27 Thread Andrew Jeffery
Hello,

This series is a couple of trivial improvements to the error message from 
linux-user's ELF loader
when it fails to mmap() the guest's address space. Both issues caused me brief 
confusion when trying
to sort myself out after hitting 
https://gitlab.com/qemu-project/qemu/-/issues/447

I've build tested the two as a sanity check.

Cheers,

Andrew

Andrew Jeffery (2):
  linux-user: elfload: s/min_mmap_addr/mmap_min_addr/
  linux-user: elfload: Specify -R is an option for qemu-user binaries

 linux-user/elfload.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

-- 
2.39.2




[PATCH 1/2] linux-user: elfload: s/min_mmap_addr/mmap_min_addr/

2023-03-27 Thread Andrew Jeffery
As-is the error message can cause some confusion as the mentioned sysctl
attribute name is wrong:

https://www.kernel.org/doc/html/latest/admin-guide/sysctl/vm.html#mmap-min-addr

Signed-off-by: Andrew Jeffery 
---
 linux-user/elfload.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1dbc1f0f9baa..601b156b476b 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2771,7 +2771,7 @@ static void pgb_reserved_va(const char *image_name, 
abi_ulong guest_loaddr,
 if (addr == MAP_FAILED || addr != test) {
 error_report("Unable to reserve 0x%lx bytes of virtual address "
  "space at %p (%s) for use as guest address space (check 
your "
- "virtual memory ulimit setting, min_mmap_addr or reserve 
less "
+ "virtual memory ulimit setting, mmap_min_addr or reserve 
less "
  "using -R option)", reserved_va, test, strerror(errno));
 exit(EXIT_FAILURE);
 }
-- 
2.39.2




[PATCH 2/2] linux-user: elfload: Specify -R is an option for qemu-user binaries

2023-03-27 Thread Andrew Jeffery
Given several different concepts are suggested for investigation, let's
not confuse e.g. ulimit's -R with what was actually intended.

Signed-off-by: Andrew Jeffery 
---
 linux-user/elfload.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 601b156b476b..694794f97202 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2772,7 +2772,8 @@ static void pgb_reserved_va(const char *image_name, 
abi_ulong guest_loaddr,
 error_report("Unable to reserve 0x%lx bytes of virtual address "
  "space at %p (%s) for use as guest address space (check 
your "
  "virtual memory ulimit setting, mmap_min_addr or reserve 
less "
- "using -R option)", reserved_va, test, strerror(errno));
+ "using qemu-user's -R option)",
+ reserved_va, test, strerror(errno));
 exit(EXIT_FAILURE);
 }
 
-- 
2.39.2




Re: [PATCH] hw/misc: Add basic Aspeed GFX model

2023-01-19 Thread Andrew Jeffery



On Thu, 19 Jan 2023, at 23:14, Joel Stanley wrote:
> Enough model to capture the pinmux writes to enable correct operation of
> the parts of pinmux that depend on GFX registers.
>
> Signed-off-by: Joel Stanley 
> ---
>  include/hw/arm/aspeed_soc.h  |   3 +
>  include/hw/misc/aspeed_gfx.h |  31 +
>  hw/arm/aspeed_ast2600.c  |  11 
>  hw/arm/aspeed_soc.c  |  12 
>  hw/misc/aspeed_gfx.c | 121 +++
>  hw/misc/meson.build  |   1 +
>  hw/misc/trace-events |   4 ++
>  7 files changed, 183 insertions(+)
>  create mode 100644 include/hw/misc/aspeed_gfx.h
>  create mode 100644 hw/misc/aspeed_gfx.c
>
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index 8389200b2d01..7084e0efeb97 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -26,6 +26,7 @@
>  #include "hw/ssi/aspeed_smc.h"
>  #include "hw/misc/aspeed_hace.h"
>  #include "hw/misc/aspeed_sbc.h"
> +#include "hw/misc/aspeed_gfx.h"
>  #include "hw/watchdog/wdt_aspeed.h"
>  #include "hw/net/ftgmac100.h"
>  #include "target/arm/cpu.h"
> @@ -81,6 +82,7 @@ struct AspeedSoCState {
>  AspeedSDHCIState emmc;
>  AspeedLPCState lpc;
>  AspeedPECIState peci;
> +AspeedGFXState gfx;
>  SerialMM uart[ASPEED_UARTS_NUM];
>  Clock *sysclk;
>  UnimplementedDeviceState iomem;
> @@ -171,6 +173,7 @@ enum {
>  ASPEED_DEV_EMMC,
>  ASPEED_DEV_KCS,
>  ASPEED_DEV_HACE,
> +ASPEED_DEV_GFX,
>  ASPEED_DEV_DPMCU,
>  ASPEED_DEV_DP,
>  ASPEED_DEV_I3C,
> diff --git a/include/hw/misc/aspeed_gfx.h b/include/hw/misc/aspeed_gfx.h
> new file mode 100644
> index ..b0736a53f577
> --- /dev/null
> +++ b/include/hw/misc/aspeed_gfx.h
> @@ -0,0 +1,31 @@
> +/*
> + * ASPEED GFX Controller
> + *
> + * Copyright (C) 2023 IBM Corp.
> + *
> + * This code is licensed under the GPL version 2 or later.  See
> + * the COPYING file in the top-level directory.
> + */

Use SPDX here?

> +
> +#ifndef ASPEED_GFX_H
> +#define ASPEED_GFX_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_ASPEED_GFX "aspeed.gfx"
> +#define ASPEED_GFX(obj) OBJECT_CHECK(AspeedGFXState, (obj), TYPE_ASPEED_GFX)
> +
> +#define ASPEED_GFX_NR_REGS (0xFC >> 2)
> +
> +typedef struct AspeedGFXState {
> +/*  */
> +SysBusDevice parent;
> +
> +/*< public >*/
> +MemoryRegion iomem;
> +qemu_irq irq;
> +
> +uint32_t regs[ASPEED_GFX_NR_REGS];
> +} AspeedGFXState;
> +
> +#endif /* _ASPEED_GFX_H_ */
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index cd75465c2bdd..10e4a13655cc 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -43,6 +43,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
>  [ASPEED_DEV_HACE]  = 0x1E6D,
>  [ASPEED_DEV_SDMC]  = 0x1E6E,
>  [ASPEED_DEV_SCU]   = 0x1E6E2000,
> +[ASPEED_DEV_GFX]   = 0x1E6E6000,
>  [ASPEED_DEV_XDMA]  = 0x1E6E7000,
>  [ASPEED_DEV_ADC]   = 0x1E6E9000,
>  [ASPEED_DEV_DP]= 0x1E6EB000,
> @@ -255,6 +256,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
> 
>  object_initialize_child(obj, "sbc", >sbc, TYPE_ASPEED_SBC);
> 
> +object_initialize_child(obj, "gfx", >gfx, TYPE_ASPEED_GFX);
> +
>  object_initialize_child(obj, "iomem", >iomem, 
> TYPE_UNIMPLEMENTED_DEVICE);
>  object_initialize_child(obj, "video", >video, 
> TYPE_UNIMPLEMENTED_DEVICE);
>  object_initialize_child(obj, "dpmcu", >dpmcu, 
> TYPE_UNIMPLEMENTED_DEVICE);
> @@ -607,6 +610,14 @@ static void aspeed_soc_ast2600_realize(DeviceState 
> *dev, Error **errp)
>  return;
>  }
>  aspeed_mmio_map(s, SYS_BUS_DEVICE(>sbc), 0, 
> sc->memmap[ASPEED_DEV_SBC]);
> +
> +/* GFX */
> +if (!sysbus_realize(SYS_BUS_DEVICE(>gfx), errp)) {
> +return;
> +}
> +aspeed_mmio_map(s, SYS_BUS_DEVICE(>gfx), 0, 
> sc->memmap[ASPEED_DEV_GFX]);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>gfx), 0,
> +   aspeed_soc_get_irq(s, ASPEED_DEV_GFX));

I think we're missing an entry for ASPEED_DEV_GFX in the irqmap array?

>  }
> 
>  static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index b05b9dd41602..053149f9ccdf 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -33,6 +33,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
>  [ASPEED_DEV_SDMC]   = 0x1E6E,
>  [ASPEED_DEV_SCU]= 0x1E6E2000,
>  [ASPEED_DEV_HACE]   = 0x1E6E3000,
> +[ASPEED_DEV_GFX]= 0x1E6E6000,
>  [ASPEED_DEV_XDMA]   = 0x1E6E7000,
>  [ASPEED_DEV_VIDEO]  = 0x1E70,
>  [ASPEED_DEV_ADC]= 0x1E6E9000,
> @@ -69,6 +70,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
>  [ASPEED_DEV_SDMC]   = 0x1E6E,
>  [ASPEED_DEV_SCU]= 0x1E6E2000,
>  [ASPEED_DEV_HACE]   = 0x1E6E3000,
> +[ASPEED_DEV_GFX]= 0x1E6E6000,
>  [ASPEED_DEV_XDMA]   = 

Re: [RFC 0/3] Add Generic SPI GPIO model

2022-07-31 Thread Andrew Jeffery



On Sun, 31 Jul 2022, at 06:48, Cédric Le Goater wrote:
> On 7/29/22 19:30, Peter Delevoryas wrote:
>> Certainly we'd like to use IRQ's instead, but she ran into correctness
>> problems. Maybe we can investigate that further and fix it.

Yes, let's not work around problems that we have the ability to fix.

>
> So much is happening in that mode.

Yes, though while there's no-doubt accidental complexity in terms of 
its implementation, the underlying hardware is also quite haphazard and 
we need an approach that scales to the large number of GPIOs it 
provides. So I'd argue there's a bunch of essential complexity involved 
as well.

Do we start with a fresh implementation that allows us to get the 
expected behaviour and then build that out to replace the current 
implementation?

Or, can we add more tests for the existing model to pin down where the 
bugs are?

> We need more trace events in the Aspeed
> GPIO model at least an extra in aspeed_gpio_update()

We can always fall back to this but my hope is we can get better test 
coverage to iron out the bugs. Maybe that gets us a more refined and 
maintainable model implementation along the way.

Cheers,

Andrew



Re: [PATCH v3 8/8] arm/aspeed: Replace mx25l25635e chip model

2022-07-25 Thread Andrew Jeffery



On Mon, 25 Jul 2022, at 16:02, Cédric Le Goater wrote:
> On 7/25/22 04:08, Andrew Jeffery wrote:
>> 
>> 
>> On Fri, 22 Jul 2022, at 16:06, Cédric Le Goater wrote:
>>> aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
>>>   mc->desc   = "OpenPOWER Witherspoon BMC (ARM1176)";
>>>   amc->soc_name  = "ast2500-a1";
>>>   amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1;
>>> -amc->fmc_model = "mx25l25635e";
>>> +amc->fmc_model = "mx25l25635f";
>> 
>> The witherspoon I checked also reported mx25l25635e in dmesg for the
>> FMC.
>> 
>> You do say "generally" in the commit message though.
>
> You can not tell from dmesg.
>
> The MX25L25635F and MX25L25635E models share the same JEDEC ID and
> the spi-nor flash device table only contains a mx25l25635e entry.
> The MX25L25635F is detected in mx25l25635_post_bfpt_fixups using SFDP.
>
> That's why I added this warning  :
>
>
> https://github.com/legoater/linux/commit/934f0708ac597022cbf6c8d6f2ce91d55025e943
>

Oh righto, sorry for the noise.



Re: [PATCH v3 8/8] arm/aspeed: Replace mx25l25635e chip model

2022-07-24 Thread Andrew Jeffery



On Fri, 22 Jul 2022, at 16:06, Cédric Le Goater wrote:
> A mx25l25635f chip model is generally found on these machines. It's
> newer and uses 4B opcodes which is better to exercise the support in
> the Linux kernel.
>
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/arm/aspeed.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 1c611284819d..7e95abc55b09 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -1157,7 +1157,7 @@ static void 
> aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
>  amc->soc_name  = "ast2400-a1";
>  amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1;
>  amc->fmc_model = "n25q256a";
> -amc->spi_model = "mx25l25635e";
> +amc->spi_model = "mx25l25635f";

Hmm, dmesg reported mx25l25635e on the palmetto I checked

>  amc->num_cs= 1;
>  amc->i2c_init  = palmetto_bmc_i2c_init;
>  mc->default_ram_size   = 256 * MiB;
> @@ -1208,7 +1208,7 @@ static void 
> aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
>  amc->soc_name  = "ast2500-a1";
>  amc->hw_strap1 = AST2500_EVB_HW_STRAP1;
>  amc->fmc_model = "mx25l25635e";
> -amc->spi_model = "mx25l25635e";
> +amc->spi_model = "mx25l25635f";
>  amc->num_cs= 1;
>  amc->i2c_init  = ast2500_evb_i2c_init;
>  mc->default_ram_size   = 512 * MiB;
> @@ -1258,7 +1258,7 @@ static void 
> aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
>  mc->desc   = "OpenPOWER Witherspoon BMC (ARM1176)";
>  amc->soc_name  = "ast2500-a1";
>  amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1;
> -amc->fmc_model = "mx25l25635e";
> +amc->fmc_model = "mx25l25635f";

The witherspoon I checked also reported mx25l25635e in dmesg for the 
FMC.

You do say "generally" in the commit message though.

Andrew



Re: [PATCH 1/2] hw/gpio/aspeed: Don't let guests modify input pins

2022-07-17 Thread Andrew Jeffery
I think we've sorted this out, but replying to finalise the conversation

On Tue, 12 Jul 2022, at 11:27, Peter Delevoryas wrote:
> On Mon, Jul 11, 2022 at 10:56:08PM +0930, Andrew Jeffery wrote:
>>  
>>  /*
>> @@ -607,7 +608,7 @@ static void aspeed_gpio_write(void *opaque, hwaddr 
>> offset, uint64_t data,
>>  data &= props->output;
>>  data = update_value_control_source(set, set->data_value, data);
>>  set->data_read = data;
>> -aspeed_gpio_update(s, set, data);
>> +aspeed_gpio_update(s, set, data, set->direction);
>>  return;
>>  case gpio_reg_direction:
>>  /*
>> @@ -683,7 +684,7 @@ static void aspeed_gpio_write(void *opaque, hwaddr 
>> offset, uint64_t data,
>>HWADDR_PRIx"\n", __func__, offset);
>>  return;
>>  }
>> -aspeed_gpio_update(s, set, set->data_value);
>> +aspeed_gpio_update(s, set, set->data_value, UINT32_MAX);
>
> Looks great overall, but why is the mode_mask UINT32_MAX here? Shouldn't it be
> set->direction? We only want to let the guest OS write to output pins, right?
> Or is that not how the register works?

The set->direction case is handled in the top hunk which handles the 
data register write. Note that it performs an early return.

The bottom hunk deals with making the value register consistent when 
we've updated any register that isn't the data register.

Andrew



Re: [PATCH 1/2] hw/gpio/aspeed: Don't let guests modify input pins

2022-07-11 Thread Andrew Jeffery



On Fri, 8 Jul 2022, at 04:34, Peter Delevoryas wrote:
> On Thu, Jul 07, 2022 at 10:53:57AM -0700, Peter Delevoryas wrote:
>> On Thu, Jul 07, 2022 at 10:56:02AM +0200, Cédric Le Goater wrote:
>> > On 7/7/22 09:17, Peter Delevoryas wrote:
>> > > It seems that aspeed_gpio_update is allowing the value for input pins to 
>> > > be
>> > > modified through register writes and QOM property modification.
>> > > 
>> > > The QOM property modification is fine, but modifying the value through
>> > > register writes from the guest OS seems wrong if the pin's direction is 
>> > > set
>> > > to input.
>> > > 
>> > > The datasheet specifies that "0" bits in the direction register select 
>> > > input
>> > > mode, and "1" selects output mode.
>> > > 
>> > > OpenBMC userspace code is accidentally writing 0's to the GPIO data
>> > > registers somewhere (or perhaps the driver is doing it through a reset or
>> > > something), and this is overwriting GPIO FRU information (board ID, slot
>> > > presence pins) that is initialized in Aspeed machine reset code (see
>> > > fby35_reset() in hw/arm/aspeed.c).
>> > 
>> > It might be good to log a GUEST_ERROR in that case, when writing to an
>> > input GPIO and when reading from an output GPIO.
>> 
>> Good idea, I'll include a GUEST_ERROR for writing to an input GPIO.
>> 
>> I'm actually not totally certain about emitting an error when reading from an
>> output GPIO, because the driver can only do 8-bit reads at the finest
>> granularity, and if 1 of the 8 pins' direction is output, then it will be
>> reading the value of an output pin. But, that's not really bad, because
>> presumably the value will be ignored. Maybe I can go test this out on
>> hardware and figure out what happens though.
>
> Did a small experiment, I was looking at some of the most significant
> bits:
>
> root@dhcp-100-96-192-133:~# devmem 0x1e78
> 0x3CFF303E
> root@dhcp-100-96-192-133:~# devmem 0x1e780004
> 0x280C
> root@dhcp-100-96-192-133:~# devmem 0x1e78 32 0x
> root@dhcp-100-96-192-133:~# devmem 0x1e780004
> 0x280C
> root@dhcp-100-96-192-133:~# devmem 0x1e78
> 0x3CFF303E
> root@dhcp-100-96-192-133:~# devmem 0x1e78
> 0x3CFF303E
> root@dhcp-100-96-192-133:~# devmem 0x1e78 32 0
> root@dhcp-100-96-192-133:~# devmem 0x1e78
> 0x14FF303A
>
> Seems like the output pin 0x2000 was initially high, and the input
> pin right next to it 0x1000 was also high. After writing 0 to the
> data register, the value in the data register changed for the output
> pin, but not the input pin.  Which matches what we're planning on doing
> in the controller.
>
> So yeah, I'll add GUEST_ERROR for writes to input pins but not output
> pins.  The driver should probably be doing a read-modify-update.
> Although...if it's not, that technically wouldn't matter, behavior
> wise...maybe GUEST_ERROR isn't appropriate for writes to input pins
> either, for the same reason as I mentioned with reads of output pins.
> I'll let you guys comment on what you think we should do.
>

With the quick hack below I think I got sensible behaviour?

```
# devmem 0x1e78
0x
# devmem 0x1e780004
0x
# devmem 0x1e780004 32 1
# devmem 0x1e78 32 1
# devmem 0x1e78
0x0001
# devmem 0x1e78 32 3
# devmem 0x1e78
0x0001
# QEMU 7.0.0 monitor - type 'help' for more information
(qemu) qom-set gpio gpioA1 on
(qemu) 

# devmem 0x1e78
0x0003
# (qemu) qom-set gpio gpioA1 off
(qemu) 

# devmem 0x1e78
0x0001
# (qemu) qom-set gpio gpioA0 off
(qemu) 
# devmem 0x1e78
0x0001
# 
```

That was with the patch below. However, I think there's a deeper issue 
with the input masking that needs to be addressed. Essentially we lack 
modelling for the actual line state, we were proxying that with 
register state. As it stands if we input-mask a line and use qom-set to 
change its state the state update will go missing. However, as Joel 
notes, I don't think we have anything configuring input masking.

diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index c63634d3d3e2..a1aa6504a8d8 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -244,7 +244,7 @@ static ptrdiff_t aspeed_gpio_set_idx(AspeedGPIOState *s, 
GPIOSets *regs)
 }
 
 static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
-   uint32_t value)
+   uint32_t value, uint32_t mode_mask)
 {
 uint32_t input_mask = regs->input_mask;
 uint32_t direction = regs->direction;
@@ -253,7 +253,8 @@ static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets 
*regs,
 uint32_t diff;
 int gpio;
 
-diff = old ^ new;
+diff = (old ^ new);
+diff &= mode_mask;
 if (diff) {
 for (gpio = 0; gpio < ASPEED_GPIOS_PER_SET; gpio++) {
 uint32_t mask = 1 << gpio;
@@ -315,7 +316,7 @@ static void aspeed_gpio_set_pin_level(AspeedGPIOState *s, 
uint32_t set_idx,
 value &= !pin_mask;
 }
 
-

Re: [PATCH 1/2] hw/gpio/aspeed: Don't let guests modify input pins

2022-07-11 Thread Andrew Jeffery



On Thu, 7 Jul 2022, at 17:50, Joel Stanley wrote:
> On Thu, 7 Jul 2022 at 07:17, Peter Delevoryas  wrote:
>>
>> It seems that aspeed_gpio_update is allowing the value for input pins to be
>> modified through register writes and QOM property modification.
>>
>> The QOM property modification is fine, but modifying the value through
>> register writes from the guest OS seems wrong if the pin's direction is set
>> to input.
>>
>> The datasheet specifies that "0" bits in the direction register select input
>> mode, and "1" selects output mode.
>>
>> OpenBMC userspace code is accidentally writing 0's to the GPIO data
>> registers somewhere (or perhaps the driver is doing it through a reset or
>> something), and this is overwriting GPIO FRU information (board ID, slot
>> presence pins) that is initialized in Aspeed machine reset code (see
>> fby35_reset() in hw/arm/aspeed.c).
>>
>> Signed-off-by: Peter Delevoryas 
>> Fixes: 4b7f956862dc ("hw/gpio: Add basic Aspeed GPIO model for AST2400 and 
>> AST2500")
>> ---
>>  hw/gpio/aspeed_gpio.c | 22 --
>>  1 file changed, 12 insertions(+), 10 deletions(-)
>>
>> diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
>> index a62a673857..2eae427201 100644
>> --- a/hw/gpio/aspeed_gpio.c
>> +++ b/hw/gpio/aspeed_gpio.c
>> @@ -268,7 +268,7 @@ static ptrdiff_t aspeed_gpio_set_idx(AspeedGPIOState *s, 
>> GPIOSets *regs)
>>  }
>>
>>  static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
>> -   uint32_t value)
>> +   uint32_t value, bool force)
>>  {
>>  uint32_t input_mask = regs->input_mask;
>>  uint32_t direction = regs->direction;
>> @@ -293,10 +293,12 @@ static void aspeed_gpio_update(AspeedGPIOState *s, 
>> GPIOSets *regs,
>>  }
>>
>
> Reading this model hurts my head a little. Perhaps we also need to add
> a test for this case to make it clear what's going on.
>
> The test above the code you've changed does this:
>
>>/* ...and we're output or not input-masked... */
>>if (!(direction & mask) && (input_mask & mask)) {
>>continue;
>>}
>
> For clarity, !(direction & mask) means "is input".
>
> The comment confuses me because it says "or", but the code has "and".

The comment documents what conditions we need before we actually go and set the
output value.

The test is whether we fail to meet those conditions.

If the condition evaluates true we don't want to modify the GPIO value, so we
`continue` to the next loop iteration to test the next GPIO.

>
> input_mask doesn't seem to feature in the Linux driver, so that will
> always be zero. The test will be X && 0, which is always 0.
>
> If you changed it to || then we would do the test that the comment
> suggests. When the pin is input, we will skip updating the value.

The condition shouldn't change, rather if the comment makes things more
confusing rather than less, we should change that instead.

Andrew



Re: [PATCH v2 0/5] hw: aspeed: Init all UART's with serial devices

2022-05-16 Thread Andrew Jeffery



On Mon, 16 May 2022, at 16:48, Cédric Le Goater wrote:
> On 5/16/22 08:23, Peter Delevoryas wrote:
>> v2:
>> - Rebased on Cedric's irq proposal. [1]
>> - Added "Introduce common UART init function" patch
>> - Added "Add uarts_num SoC attribute" patch
>> - Rewrote last commit's message for clarity
>
> Looks good to me.
>
>> I tried testing this by running acceptance tests, particularly the
>> boot_linux_console.py file, but I had to disable the raspi2_initrd case.
>> It's not related to my changes (A/B tested and it fails on upstream/master
>> too), but thought I would mention that.>
>> I also manually tested several machines:
>> 
>> AST2400: 
>> https://github.com/facebook/openbmc/releases/download/v2021.49.0/wedge100.mtd
>> AST2500: 
>> https://github.com/facebook/openbmc/releases/download/v2021.49.0/fby3.mtd
>> AST2600: 
>> https://github.com/facebook/openbmc/releases/download/v2021.49.0/fuji.mtd
>> AST1030: 
>> https://github.com/peterdelevoryas/OpenBIC/releases/download/oby35-cl-2022.13.01/Y35BCL.elf
>> 
>> [1] https://lore.kernel.org/qemu-devel/20220516055620.2380197-1-...@kaod.org/
> I have quite a few images which I run manually. OpenBMC is providing
> images, Aspeed also. Joel did a small tool for the IBM rainier :
>
>https://github.com/shenki/qemu-boot-test
>
> Having an automated framework for Aspeed machines pulling images
> from different places would be nice but we cannot put all under
> QEMU.

For what it's worth I run this as a smoke test before pushing updates to 
openbmc/qemu:

https://github.com/openbmc/openbmc-build-scripts/blob/master/scripts/test-qemu

Andrew



Re: [PATCH 0/3] hw: aspeed_gpio: Model new interface for the AST2600

2022-02-09 Thread Andrew Jeffery



On Tue, 8 Feb 2022, at 01:34, Andrew Jeffery wrote:
> Hello,
>
> This series adds support for a new register interface supported by the
> Aspeed GPIO controller, present in at least the AST2600.
>
> The new interface is a single register implementing an indirect command
> protocol that allows us to manipulate up to (at least) 208 GPIOs. This
> makes it possible to write very simple drivers for e.g. u-boot and
> jettison the need for the tedious data model required to deal with the
> old register layout.
>
> I've lightly tested the device consistency under Linux. The Linux
> driver is implemented in terms of the old interface, so data model
> consistency can be tested one way by poking the driver using the
> libgpiod tools and then the other using devmem to drive the new
> interface.
>
> Please review!

Naturally further testing revealed some quirks that require further 
enhancements to the modelling.

Hold off on doing anything with this series for the moment.

Cheers,

Andrew



[PATCH 1/3] hw: aspeed_gpio: Cleanup stray semicolon after switch

2022-02-07 Thread Andrew Jeffery
Not sure how that got there.

Signed-off-by: Andrew Jeffery 
---
 hw/gpio/aspeed_gpio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index 911d21c8cfbe..c63634d3d3e2 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -571,7 +571,7 @@ static uint64_t aspeed_gpio_read(void *opaque, hwaddr 
offset, uint32_t size)
 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
   HWADDR_PRIx"\n", __func__, offset);
 return 0;
-};
+}
 }
 
 static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
-- 
2.32.0




[PATCH 0/3] hw: aspeed_gpio: Model new interface for the AST2600

2022-02-07 Thread Andrew Jeffery
Hello,

This series adds support for a new register interface supported by the
Aspeed GPIO controller, present in at least the AST2600.

The new interface is a single register implementing an indirect command
protocol that allows us to manipulate up to (at least) 208 GPIOs. This
makes it possible to write very simple drivers for e.g. u-boot and
jettison the need for the tedious data model required to deal with the
old register layout.

I've lightly tested the device consistency under Linux. The Linux
driver is implemented in terms of the old interface, so data model
consistency can be tested one way by poking the driver using the
libgpiod tools and then the other using devmem to drive the new
interface.

Please review!

Andrew

Andrew Jeffery (3):
  hw: aspeed_gpio: Cleanup stray semicolon after switch
  hw: aspeed_gpio: Split GPIOSet handling from accessors
  hw: aspeed_gpio: Support the AST2600's indexed register interface

 hw/gpio/aspeed_gpio.c | 305 --
 include/hw/gpio/aspeed_gpio.h |   3 +
 2 files changed, 261 insertions(+), 47 deletions(-)

-- 
2.32.0




[PATCH 3/3] hw: aspeed_gpio: Support the AST2600's indexed register interface

2022-02-07 Thread Andrew Jeffery
A new register interface was added to the AST2600 GPIO controller that
allows a single 32 bit register to drive configuration of up to 208
GPIOs. This makes way for a very simple driver implementation in
early-boot firmware such as u-boot. The old register interface required
drivers implement a tedious data model, but allowed efficient multi-line
bit-banging.

Either way, the hardware model in qemu becomes quite complex, though it
would have been less so had the new interface been the only one
available.

Signed-off-by: Andrew Jeffery 
---
 hw/gpio/aspeed_gpio.c | 202 +-
 include/hw/gpio/aspeed_gpio.h |   3 +
 2 files changed, 202 insertions(+), 3 deletions(-)

diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index 1d4d1aedc4b5..cee1a9a2e065 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -160,7 +160,42 @@
 #define GPIO_YZAAAB_DIRECTION  (0x1E4 >> 2)
 #define GPIO_AC_DATA_VALUE (0x1E8 >> 2)
 #define GPIO_AC_DIRECTION  (0x1EC >> 2)
-#define GPIO_3_3V_MEM_SIZE 0x1F0
+#define GPIO_INDEX (0x2AC >> 2)
+#define  GPIO_INDEX_DATA_SHIFT 20
+#define  GPIO_INDEX_DATA_LEN   12
+#define   GPIO_INDEX_DATA_DATA 20
+#define   GPIO_INDEX_DATA_DIR  20
+#define   GPIO_INDEX_DATA_IRQ_EN   20
+#define   GPIO_INDEX_DATA_IRQ_TY0  21
+#define   GPIO_INDEX_DATA_IRQ_TY1  22
+#define   GPIO_INDEX_DATA_IRQ_TY2  23
+#define   GPIO_INDEX_DATA_IRQ_STS  24
+#define   GPIO_INDEX_DATA_DB1  20
+#define   GPIO_INDEX_DATA_DB2  21
+#define   GPIO_INDEX_DATA_TOL  20
+#define   GPIO_INDEX_DATA_SRC0 20
+#define   GPIO_INDEX_DATA_SRC1 20
+#define   GPIO_INDEX_DATA_INPUT20
+#define   GPIO_INDEX_DATA_WR_SRC   20
+#define  GPIO_INDEX_TYPE_SHIFT 16
+#define  GPIO_INDEX_TYPE_LEN   4
+#define   GPIO_INDEX_TYPE_DATA 0
+#define   GPIO_INDEX_TYPE_DIR  1
+#define   GPIO_INDEX_TYPE_IRQ  2
+#define   GPIO_INDEX_TYPE_DEBOUNCE 3
+#define   GPIO_INDEX_TYPE_TOL  4
+#define   GPIO_INDEX_TYPE_SRC  5
+#define   GPIO_INDEX_TYPE_INPUT6
+#define   GPIO_INDEX_TYPE_RSVD 7
+#define   GPIO_INDEX_TYPE_WR_SRC   8
+#define   GPIO_INDEX_TYPE_RD_SRC   9
+#define  GPIO_INDEX_CMD_SHIFT  12
+#define  GPIO_INDEX_CMD_LEN1
+#define   GPIO_INDEX_CMD_WRITE 0
+#define   GPIO_INDEX_CMD_READ  1
+#define  GPIO_INDEX_NR_SHIFT   0
+#define  GPIO_INDEX_NR_LEN 8
+#define GPIO_3_3V_MEM_SIZE 0x2B0
 #define GPIO_3_3V_REG_ARRAY_SIZE   (GPIO_3_3V_MEM_SIZE >> 2)
 
 /* AST2600 only - 1.8V gpios */
@@ -571,6 +606,11 @@ static uint64_t aspeed_gpio_read(void *opaque, hwaddr 
offset, uint32_t size)
 return (uint64_t) s->debounce_regs[idx];
 }
 
+/* This is a (new, indirect) register interface for configuring GPIOs */
+if (agc->have_index_reg && idx == GPIO_INDEX) {
+return (uint64_t) s->index;
+}
+
 reg = >reg_table[idx];
 if (reg->set_idx >= agc->nr_gpio_sets) {
 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
@@ -581,8 +621,73 @@ static uint64_t aspeed_gpio_read(void *opaque, hwaddr 
offset, uint32_t size)
 return aspeed_gpio_set_read(s, reg);
 }
 
-static void aspeed_gpio_set_write(AspeedGPIOState *s, const AspeedGPIOReg *reg,
-  uint32_t data)
+static int aspeed_gpio_set_offset_read(AspeedGPIOState *s, int set, enum 
GPIORegType reg,
+   int offset)
+{
+return !!(aspeed_gpio_set_read(s, &(AspeedGPIOReg){set, reg}) & 
BIT(offset));
+}
+
+static const enum GPIORegType aspeed_gpio_index_type_map[] = {
+   [GPIO_INDEX_TYPE_DATA] = gpio_reg_data_value,
+   [GPIO_INDEX_TYPE_DIR] = gpio_reg_direction,
+   [GPIO_INDEX_TYPE_TOL] = gpio_reg_reset_tolerant,
+   [GPIO_INDEX_TYPE_INPUT] = gpio_reg_input_mask,
+   [GPIO_INDEX_TYPE_WR_SRC] = gpio_reg_input_mask /* See GPIO2AC doc */
+};
+
+static void
+aspeed_gpio_index_read(AspeedGPIOState *s, uint32_t type, uint32_t number)
+{
+int pin = number % 32;
+int set = number / 32;
+
+/* Clear the data field so we can OR into it without further data 
dependencies */
+s->index = deposit32(s->index, GPIO_INDEX_DATA_SHIFT, GPIO_INDEX_DATA_LEN, 
0);
+
+switch (type) {
+case GPIO_INDEX_TYPE_DATA:
+case GPIO_INDEX_TYPE_DIR:
+case GPIO_INDEX_TYPE_TOL:
+case GPIO_INDEX_TYPE_INPUT:
+case GPIO_INDEX_TYPE_WR_SRC:
+{
+enum GPIORegType reg = aspeed_gpio_index_type_map[type];
+s->index |= deposit32(0, GPIO_INDEX_DATA_SHIFT, GPIO_INDEX_DATA_LEN,
+  aspeed_gpio_set_offset_read(s, set, reg, pin));
+break;
+}
+case GPIO_INDEX_TYPE_IRQ:
+s->index |= deposit32(0, GPIO_INDEX_DATA_IRQ_EN, 1,
+aspeed_gpio_set_offset_read(s, set, 
gpio_reg_int_enable, pin));
+s->index |= deposit32(0, GPIO_INDEX_DATA_I

[PATCH 2/3] hw: aspeed_gpio: Split GPIOSet handling from accessors

2022-02-07 Thread Andrew Jeffery
Pave the way for implementing the new register interface for GPIO
control provided by the AST2600. We need a consistent data model, so
do some work to enable use of the AspeedGPIOReg / GPIOSets data
structures for both.

Signed-off-by: Andrew Jeffery 
---
 hw/gpio/aspeed_gpio.c | 105 --
 1 file changed, 60 insertions(+), 45 deletions(-)

diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index c63634d3d3e2..1d4d1aedc4b5 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -516,28 +516,11 @@ static const AspeedGPIOReg 
aspeed_1_8v_gpios[GPIO_1_8V_REG_ARRAY_SIZE] = {
 [GPIO_1_8V_E_INPUT_MASK] = {1, gpio_reg_input_mask},
 };
 
-static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
+static uint64_t
+aspeed_gpio_set_read(const AspeedGPIOState *s, const AspeedGPIOReg *reg)
 {
-AspeedGPIOState *s = ASPEED_GPIO(opaque);
-AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
-uint64_t idx = -1;
-const AspeedGPIOReg *reg;
-GPIOSets *set;
+const GPIOSets *set = >sets[reg->set_idx];
 
-idx = offset >> 2;
-if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
-idx -= GPIO_DEBOUNCE_TIME_1;
-return (uint64_t) s->debounce_regs[idx];
-}
-
-reg = >reg_table[idx];
-if (reg->set_idx >= agc->nr_gpio_sets) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
-  HWADDR_PRIx"\n", __func__, offset);
-return 0;
-}
-
-set = >sets[reg->set_idx];
 switch (reg->type) {
 case gpio_reg_data_value:
 return set->data_value;
@@ -567,37 +550,44 @@ static uint64_t aspeed_gpio_read(void *opaque, hwaddr 
offset, uint32_t size)
 return set->data_read;
 case gpio_reg_input_mask:
 return set->input_mask;
-default:
+case gpio_not_a_reg:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid register: %d\n", __func__,
+  reg->type);
+}
+
+return 0;
+}
+
+static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
+{
+AspeedGPIOState *s = ASPEED_GPIO(opaque);
+AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+const AspeedGPIOReg *reg;
+uint64_t idx = -1;
+
+idx = offset >> 2;
+if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
+idx -= GPIO_DEBOUNCE_TIME_1;
+return (uint64_t) s->debounce_regs[idx];
+}
+
+reg = >reg_table[idx];
+if (reg->set_idx >= agc->nr_gpio_sets) {
 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
   HWADDR_PRIx"\n", __func__, offset);
 return 0;
 }
+
+return aspeed_gpio_set_read(s, reg);
 }
 
-static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
-  uint32_t size)
+static void aspeed_gpio_set_write(AspeedGPIOState *s, const AspeedGPIOReg *reg,
+  uint32_t data)
 {
-AspeedGPIOState *s = ASPEED_GPIO(opaque);
 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
 const GPIOSetProperties *props;
-uint64_t idx = -1;
-const AspeedGPIOReg *reg;
-GPIOSets *set;
 uint32_t cleared;
-
-idx = offset >> 2;
-if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
-idx -= GPIO_DEBOUNCE_TIME_1;
-s->debounce_regs[idx] = (uint32_t) data;
-return;
-}
-
-reg = >reg_table[idx];
-if (reg->set_idx >= agc->nr_gpio_sets) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
-  HWADDR_PRIx"\n", __func__, offset);
-return;
-}
+GPIOSets *set;
 
 set = >sets[reg->set_idx];
 props = >props[reg->set_idx];
@@ -678,13 +668,38 @@ static void aspeed_gpio_write(void *opaque, hwaddr 
offset, uint64_t data,
  */
  set->input_mask = data & props->input;
 break;
-default:
-qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
-  HWADDR_PRIx"\n", __func__, offset);
+case gpio_not_a_reg:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid register: %d\n", __func__,
+  reg->type);
 return;
 }
+
 aspeed_gpio_update(s, set, set->data_value);
-return;
+}
+
+static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
+  uint32_t size)
+{
+AspeedGPIOState *s = ASPEED_GPIO(opaque);
+AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
+const AspeedGPIOReg *reg;
+uint64_t idx = -1;
+
+idx = offset >> 2;
+if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
+idx -= GPIO_DEBOUN

Re: [PATCH] MAINTAINERS: Change status to Odd Fixes

2021-11-02 Thread Andrew Jeffery



On Wed, 3 Nov 2021, at 02:48, Peter Maydell wrote:
> On Mon, 1 Nov 2021 at 18:31, Cédric Le Goater  wrote:
>>
>> I haven't done any Aspeed development for a couple of years now and
>> maintaining the Aspeed QEMU machines has been a side project since.
>> I don't have time anymore.
>
> Thanks for the work you've done on this over the years.

Second this!

>
> I guess this means I should start picking up aspeed-related
> patches into the target-arm queue again ?

I'd struggle taking it on - my qemu development is pretty sporadic and 
hackish at best and my patches need the review. Unless Joel wants to 
take the role I think it would be best if our patches went via 
target-arm again.

A general thanks for your help here too Peter :)

Andrew



Re: [PATCH 2/5] hw/arm/aspeed: Select console UART from machine

2021-08-31 Thread Andrew Jeffery
Hi Cédric, Peter,

On Tue, 31 Aug 2021, at 20:09, Cédric Le Goater wrote:
> On 8/28/21 5:58 PM, Peter Delevoryas wrote:
> > I think I’m a little confused on this part. What I meant by “most machines 
> > just use UART5” was that most DTS’s use “stdout-path=”, but fuji uses 
> > “stdout-path=”. I /do/ see that SCU510 includes a bit related to 
> > UART, but it’s for disabling booting from UART1 and UART5. I just care 
> > about the console aspect, not booting.
> 
> The UART can be switched with SCU70[29] on the AST2500, btw.

If it helps, neither the AST2600's "Boot from UART" feature nor the 
AST2[456]00's "Debug UART" feature are related to which UART is used as 
the BMC console by u-boot and/or the kernel - the latter is entirely a 
software thing.

The "Debug UART" is a hardware backdoor, a UART-to-AHB bridge 
implemented by the SoC. It provides a shell environment that allows you 
to issue transactions directly on the AHB if you perform a magic knock. 
I have a driver for it implemented here:

https://github.com/amboar/cve-2019-6260/blob/master/src/debug.c

SCU70[29] on the AST2500 selects whether this backdoor is exposed on 
UART1 or UART5.

The "Boot from UART" feature is implemented in the AST2600 ROM code as 
a fallback for loading the SPL if fetching it from SPI-NOR or the eMMC 
fails, or the SPL is incorrectly signed for secure-boot.

I think Peter is on the right track with this patch?

Andrew



[PATCH] misc/pca9552: Fix LED status register indexing in pca955x_get_led()

2021-07-22 Thread Andrew Jeffery
There was a bit of a thinko in the state calculation where every odd pin
in was reported in e.g. "pwm0" mode rather than "off". This was the
result of an incorrect bit shift for the 2-bit field representing each
LED state.

Fixes: a90d8f84674d ("misc/pca9552: Add qom set and get")
Signed-off-by: Andrew Jeffery 
---
 hw/misc/pca9552.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/pca9552.c b/hw/misc/pca9552.c
index b7686e27d7fa..fff19e369a39 100644
--- a/hw/misc/pca9552.c
+++ b/hw/misc/pca9552.c
@@ -272,7 +272,7 @@ static void pca955x_get_led(Object *obj, Visitor *v, const 
char *name,
  * reading the INPUTx reg
  */
 reg = PCA9552_LS0 + led / 4;
-state = (pca955x_read(s, reg) >> (led % 8)) & 0x3;
+state = (pca955x_read(s, reg) >> ((led % 4) * 2)) & 0x3;
 visit_type_str(v, name, (char **)_state[state], errp);
 }
 
-- 
2.30.2




Re: [PATCH 2/2] watchdog: aspeed: Fix sequential control writes

2021-07-12 Thread Andrew Jeffery



On Fri, 9 Jul 2021, at 16:59, Philippe Mathieu-Daudé wrote:
> On 7/9/21 7:31 AM, Andrew Jeffery wrote:
> > The logic in the handling for the control register required toggling the
> > enable state for writes to stick. Rework the condition chain to allow
> > sequential writes that do not update the enable state.
> > 
> > Fixes: 854123bf8d4b ("wdt: Add Aspeed watchdog device model")
> > Signed-off-by: Andrew Jeffery 
> > ---
> >  hw/watchdog/wdt_aspeed.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
> > index faa3d35fdf21..69c37af9a6e9 100644
> > --- a/hw/watchdog/wdt_aspeed.c
> > +++ b/hw/watchdog/wdt_aspeed.c
> > @@ -166,6 +166,8 @@ static void aspeed_wdt_write(void *opaque, hwaddr 
> > offset, uint64_t data,
> >  } else if (!enable && aspeed_wdt_is_enabled(s)) {
> >  s->regs[WDT_CTRL] = data;
> >  timer_del(s->timer);
> > +} else {
> > +s->regs[WDT_CTRL] = data;
> 
> What about simplifying by moving here:
> 
>if (!enable && aspeed_wdt_is_enabled(s)) {
>timer_del(s->timer);
>}
> 

I don't think that works, as aspeed_wdt_is_enabled() tests the value of 
s->regs[WDT_CTRL]. If you set it before you test then you end up in the 
wrong state.

Andrew



[PATCH 1/2] watchdog: aspeed: Sanitize control register values

2021-07-08 Thread Andrew Jeffery
While some of the critical fields remain the same, there is variation in
the definition of the control register across the SoC generations.
Reserved regions are adjusted, while in other cases the mutability or
behaviour of fields change.

Introduce a callback to sanitize the value on writes to ensure model
behaviour reflects the hardware.

Fixes: 854123bf8d4b ("wdt: Add Aspeed watchdog device model")
Signed-off-by: Andrew Jeffery 
---
 hw/watchdog/wdt_aspeed.c | 24 ++--
 include/hw/watchdog/wdt_aspeed.h |  1 +
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index 6352ba1b0e5b..faa3d35fdf21 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -118,13 +118,27 @@ static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
 }
 }
 
+static uint64_t aspeed_2400_sanitize_ctrl(uint64_t data)
+{
+return data & 0x;
+}
+
+static uint64_t aspeed_2500_sanitize_ctrl(uint64_t data)
+{
+return (data & ~(0xfUL << 8)) | WDT_CTRL_1MHZ_CLK;
+}
+
+static uint64_t aspeed_2600_sanitize_ctrl(uint64_t data)
+{
+return data & ~(0x7UL << 7);
+}
 
 static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
  unsigned size)
 {
 AspeedWDTState *s = ASPEED_WDT(opaque);
 AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
-bool enable = data & WDT_CTRL_ENABLE;
+bool enable;
 
 offset >>= 2;
 
@@ -144,6 +158,8 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, 
uint64_t data,
 }
 break;
 case WDT_CTRL:
+data = awc->sanitize_ctrl(data);
+enable = data & WDT_CTRL_ENABLE;
 if (enable && !aspeed_wdt_is_enabled(s)) {
 s->regs[WDT_CTRL] = data;
 awc->wdt_reload(s);
@@ -207,11 +223,12 @@ static const MemoryRegionOps aspeed_wdt_ops = {
 static void aspeed_wdt_reset(DeviceState *dev)
 {
 AspeedWDTState *s = ASPEED_WDT(dev);
+AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
 
 s->regs[WDT_STATUS] = 0x3EF1480;
 s->regs[WDT_RELOAD_VALUE] = 0x03EF1480;
 s->regs[WDT_RESTART] = 0;
-s->regs[WDT_CTRL] = 0;
+s->regs[WDT_CTRL] = awc->sanitize_ctrl(0);
 s->regs[WDT_RESET_WIDTH] = 0xFF;
 
 timer_del(s->timer);
@@ -293,6 +310,7 @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, 
void *data)
 awc->ext_pulse_width_mask = 0xff;
 awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
 awc->wdt_reload = aspeed_wdt_reload;
+awc->sanitize_ctrl = aspeed_2400_sanitize_ctrl;
 }
 
 static const TypeInfo aspeed_2400_wdt_info = {
@@ -328,6 +346,7 @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, 
void *data)
 awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
 awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
 awc->wdt_reload = aspeed_wdt_reload_1mhz;
+awc->sanitize_ctrl = aspeed_2500_sanitize_ctrl;
 }
 
 static const TypeInfo aspeed_2500_wdt_info = {
@@ -348,6 +367,7 @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, 
void *data)
 awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
 awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
 awc->wdt_reload = aspeed_wdt_reload_1mhz;
+awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
 }
 
 static const TypeInfo aspeed_2600_wdt_info = {
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
index 80b03661e303..f945cd6c5833 100644
--- a/include/hw/watchdog/wdt_aspeed.h
+++ b/include/hw/watchdog/wdt_aspeed.h
@@ -44,6 +44,7 @@ struct AspeedWDTClass {
 uint32_t reset_ctrl_reg;
 void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
 void (*wdt_reload)(AspeedWDTState *s);
+uint64_t (*sanitize_ctrl)(uint64_t data);
 };
 
 #endif /* WDT_ASPEED_H */
-- 
2.30.2




[PATCH 2/2] watchdog: aspeed: Fix sequential control writes

2021-07-08 Thread Andrew Jeffery
The logic in the handling for the control register required toggling the
enable state for writes to stick. Rework the condition chain to allow
sequential writes that do not update the enable state.

Fixes: 854123bf8d4b ("wdt: Add Aspeed watchdog device model")
Signed-off-by: Andrew Jeffery 
---
 hw/watchdog/wdt_aspeed.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index faa3d35fdf21..69c37af9a6e9 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -166,6 +166,8 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, 
uint64_t data,
 } else if (!enable && aspeed_wdt_is_enabled(s)) {
 s->regs[WDT_CTRL] = data;
 timer_del(s->timer);
+} else {
+s->regs[WDT_CTRL] = data;
 }
 break;
 case WDT_RESET_WIDTH:
-- 
2.30.2




[PATCH 0/2] wdt_aspeed: Fix behaviour of control register

2021-07-08 Thread Andrew Jeffery
Hello,

I discovered a couple of bugs in the watchdog while testing a tool to poke
Aspeed BMCs over their various AHB bridges. The immediate observation was that
the model for the 2500 wasn't signalling use of the fixed 1MHz clock, which is
resolved in the first patch. The other observation was that sequential writes to
control weren't sticking if the enable bit wasn't toggled, which is fixed in the
second patch.

Please review.

Andrew

Andrew Jeffery (2):
  watchdog: aspeed: Sanitize control register values
  watchdog: aspeed: Fix sequential control writes

 hw/watchdog/wdt_aspeed.c | 26 --
 include/hw/watchdog/wdt_aspeed.h |  1 +
 2 files changed, 25 insertions(+), 2 deletions(-)

-- 
2.30.2




Re: [PATCH] arm/aspeed: rainier: Add i2c eeproms and muxes

2021-06-27 Thread Andrew Jeffery



On Fri, 25 Jun 2021, at 14:36, Joel Stanley wrote:
> These are the devices documented by the Rainier device tree. With this
> we can see the guest discovering the multiplexers and probing the eeprom
> devices:
> 
>  i2c i2c-2: Added multiplexed i2c bus 16
>  i2c i2c-2: Added multiplexed i2c bus 17
>  i2c i2c-2: Added multiplexed i2c bus 18
>  i2c i2c-2: Added multiplexed i2c bus 19
>  i2c-mux-gpio i2cmux: 4 port mux on 1e78a180.i2c-bus adapter
>  at24 20-0050: 8192 byte 24c64 EEPROM, writable, 1 bytes/write
>  i2c i2c-4: Added multiplexed i2c bus 20
>  at24 21-0051: 8192 byte 24c64 EEPROM, writable, 1 bytes/write
>  i2c i2c-4: Added multiplexed i2c bus 21
>  at24 22-0052: 8192 byte 24c64 EEPROM, writable, 1 bytes/write
> 
> Signed-off-by: Joel Stanley 
> ---
>  hw/arm/aspeed.c | 56 +
>  1 file changed, 56 insertions(+)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 1301e8fdffb2..7ed22294c6eb 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -677,6 +677,10 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
>  static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
>  {
>  AspeedSoCState *soc = >soc;
> +I2CSlave *i2c_mux;
> +
> +smbus_eeprom_init_one(aspeed_i2c_get_bus(>i2c, 0), 0x51,
> +  g_malloc0(32 * 1024));
>  
>  /* The rainier expects a TMP275 but a TMP105 is compatible */
>  i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4), TYPE_TMP105,
> @@ -685,11 +689,25 @@ static void rainier_bmc_i2c_init(AspeedMachineState 
> *bmc)
>   0x49);
>  i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4), TYPE_TMP105,
>   0x4a);
> +i2c_mux = i2c_slave_create_simple(aspeed_i2c_get_bus(>i2c, 4),
> +  "pca9546", 0x70);
> +smbus_eeprom_init_one(pca954x_i2c_get_bus(i2c_mux, 0), 0x50,
> +  g_malloc0(64 * 1024));

The EEPROMs described in the Rainier devicetree are Atmel AT2x devices and
not SMBus EEPROMs. The SMBus EEPROM model uses SMBus block reads and 
writes which are not what the AT2x driver issues. If you try to read or 
write data under Linux from the EEPROMs in this patch you just get 
corrupt results. So as far as I can see the patch needs to be reworked.

Andrew



Re: RFC: Memory region accesses where .valid.min_access_size < .impl.min_access_size

2021-05-13 Thread Andrew Jeffery



On Thu, 13 May 2021, at 22:30, Jonathan Cameron wrote:
> On Thu, 13 May 2021 14:36:27 +0200
> Philippe Mathieu-Daudé  wrote:
> 
> > On 5/13/21 2:23 PM, Peter Maydell wrote:
> > > On Thu, 13 May 2021 at 12:49, Jonathan Cameron
> > >  wrote:  
> > >> My initial suggestion was to fix this by adding the relatively
> > >> simple code needed in the driver to implement byte read / write,
> > >> but Ben pointed at the QEMU docs - docs/devel/memory.rst which
> > >> says
> > >> "
> > >> .impl.min_access_size, .impl.max_access_size define the access sizes
> > >>(in bytes) supported by the *implementation*; other access sizes will 
> > >> be
> > >>emulated using the ones available. For example a 4-byte write will be
> > >>emulated using four 1-byte writes, if .impl.max_access_size = 1.
> > >> "
> > >>
> > >> This isn't true when we have the situation where
> > >> .valid.min_access_size < .imp.min_access_size
> > >>
> > >> So change the docs or try to make this work?  
> > 
> > See also this patch from Francisco:
> > https://www.mail-archive.com/qemu-devel@nongnu.org/msg636935.html
> > 
> > And full unaligned access support from Andrew:
> > https://www.mail-archive.com/qemu-devel@nongnu.org/msg461247.html

Much better to use lore.kernel.org:

https://lore.kernel.org/qemu-devel/20170630030058.28943-1-and...@aj.id.au/

because...

> 
> Thanks - that's very similar to what I was carrying, but I think it
> only covers the read case.  That's backed up by the comment:
> /* XXX: Can't do this hack for writes */

It becomes easier to find Paolo's suggestion to fix that here:

https://lore.kernel.org/qemu-devel/cd1aba90-176f-9ec6-3e2b-d1135156a...@redhat.com/

Would love to see this resolved! Unfortunately I haven't had the 
bandwidth to fix it all up for ... a long time now.

Andrew



Re: [PATCH] aspeed: Emulate the AST2600A3

2021-04-12 Thread Andrew Jeffery



On Tue, 13 Apr 2021, at 00:57, Cédric Le Goater wrote:
> On 3/4/21 1:43 PM, Joel Stanley wrote:
> > This is the latest revision of the ASPEED 2600 SoC.
> 
> Should we change all machines to use the new SoC ? 
> 
> I would prefer if we introduced an "ast2600-a3" Aspeed SoC, that we would 
> use for the newer rainier machine, and leave the tacoma-bmc and ast2600-evb 
> machines as they are.

I think we just change them all. We're not going to see pre-A3 chips in 
production systems.

Andrew



Re: [PATCH v5 1/3] hw: Model ASPEED's Hash and Crypto Engine

2021-04-08 Thread Andrew Jeffery



On Fri, 9 Apr 2021, at 09:32, Joel Stanley wrote:
> The HACE (Hash and Crypto Engine) is a device that offloads MD5, SHA1,
> SHA2, RSA and other cryptographic algorithms.
> 
> This initial model implements a subset of the device's functionality;
> currently only MD5/SHA hashing, and on the ast2600's scatter gather
> engine.
> 
> Co-developed-by: Klaus Heinrich Kiwi 
> Reviewed-by: Cédric Le Goater 
> Reviewed-by: Philippe Mathieu-Daudé 
> Signed-off-by: Joel Stanley 

Reviewed-by: Andrew Jeffery 



Re: [PATCH v3 1/3] hw: Model ASPEED's Hash and Crypto Engine

2021-03-16 Thread Andrew Jeffery



On Fri, 12 Mar 2021, at 21:27, Joel Stanley wrote:
> The HACE (Hash and Crypto Engine) is a device that offloads MD5, SHA1,
> SHA2, RSA and other cryptographic algorithms.
> 
> This initial model implements a subset of the device's functionality;
> currently only direct access (non-scatter gather) hashing.
> 
> Signed-off-by: Joel Stanley 
> Signed-off-by: Cédric Le Goater 
> ---
> v3:
>  - rebase on upstream to fix meson.build conflict
> v2:
>  - reorder register defines
>  - mask src/dest/len registers according to hardware
> ---
>  include/hw/misc/aspeed_hace.h |  33 
>  hw/misc/aspeed_hace.c | 312 ++
>  hw/misc/meson.build   |   1 +
>  3 files changed, 346 insertions(+)
>  create mode 100644 include/hw/misc/aspeed_hace.h
>  create mode 100644 hw/misc/aspeed_hace.c
> 
> diff --git a/include/hw/misc/aspeed_hace.h 
> b/include/hw/misc/aspeed_hace.h
> new file mode 100644
> index ..e1fce670ef9e
> --- /dev/null
> +++ b/include/hw/misc/aspeed_hace.h
> @@ -0,0 +1,33 @@
> +/*
> + * ASPEED Hash and Crypto Engine
> + *
> + * Copyright (C) 2021 IBM Corp.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef ASPEED_HACE_H
> +#define ASPEED_HACE_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_ASPEED_HACE "aspeed.hace"
> +#define ASPEED_HACE(obj) OBJECT_CHECK(AspeedHACEState, (obj), 
> TYPE_ASPEED_HACE)
> +
> +#define ASPEED_HACE_NR_REGS (0x64 >> 2)
> +
> +typedef struct AspeedHACEState {
> +/*  */
> +SysBusDevice parent;
> +
> +/*< public >*/
> +MemoryRegion iomem;
> +qemu_irq irq;
> +
> +uint32_t regs[ASPEED_HACE_NR_REGS];
> +
> +MemoryRegion *dram_mr;
> +AddressSpace dram_as;
> +} AspeedHACEState;
> +
> +#endif /* _ASPEED_HACE_H_ */
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> new file mode 100644
> index ..3d02fae2dd62
> --- /dev/null
> +++ b/hw/misc/aspeed_hace.c
> @@ -0,0 +1,312 @@
> +/*
> + * ASPEED Hash and Crypto Engine
> + *
> + * Copyright (C) 2021 IBM Corp.
> + *
> + * Joel Stanley 
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qemu/error-report.h"
> +#include "hw/misc/aspeed_hace.h"
> +#include "qapi/error.h"
> +#include "migration/vmstate.h"
> +#include "crypto/hash.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/irq.h"
> +
> +#define R_CRYPT_CMD (0x10 / 4)
> +
> +#define R_STATUS(0x1c / 4)
> +#define HASH_IRQBIT(9)
> +#define CRYPT_IRQ   BIT(12)
> +#define TAG_IRQ BIT(15)
> +
> +#define R_HASH_SRC  (0x20 / 4)
> +#define R_HASH_DEST (0x24 / 4)
> +#define R_HASH_SRC_LEN  (0x2c / 4)
> +
> +#define R_HASH_CMD  (0x30 / 4)
> +/* Hash algorithim selection */
> +#define  HASH_ALGO_MASK (BIT(4) | BIT(5) | BIT(6))
> +#define  HASH_ALGO_MD5  0
> +#define  HASH_ALGO_SHA1 BIT(5)
> +#define  HASH_ALGO_SHA224   BIT(6)
> +#define  HASH_ALGO_SHA256   (BIT(4) | BIT(6))
> +#define  HASH_ALGO_SHA512_SERIES(BIT(5) | BIT(6))
> +/* SHA512 algorithim selection */
> +#define  SHA512_HASH_ALGO_MASK  (BIT(10) | BIT(11) | BIT(12))
> +#define  HASH_ALGO_SHA512_SHA5120
> +#define  HASH_ALGO_SHA512_SHA384BIT(10)
> +#define  HASH_ALGO_SHA512_SHA256BIT(11)
> +#define  HASH_ALGO_SHA512_SHA224(BIT(10) | BIT(11))
> +/* HMAC modes */
> +#define  HASH_HMAC_MASK (BIT(7) | BIT(8))
> +#define  HASH_DIGEST0
> +#define  HASH_DIGEST_HMAC   BIT(7)
> +#define  HASH_DIGEST_ACCUM  BIT(8)
> +#define  HASH_HMAC_KEY  (BIT(7) | BIT(8))
> +/* Cascscaed operation modes */
> +#define  HASH_ONLY  0
> +#define  HASH_ONLY2 BIT(0)
> +#define  HASH_CRYPT_THEN_HASH   BIT(1)
> +#define  HASH_HASH_THEN_CRYPT   (BIT(0) | BIT(1))
> +/* Other cmd bits */
> +#define  HASH_IRQ_ENBIT(9)
> +#define  HASH_SG_EN BIT(18)
> +
> +
> +static int do_hash_operation(AspeedHACEState *s, int algo)
> +{
> +hwaddr src, len, dest;
> +uint8_t *digest_buf = NULL;
> +size_t digest_len = 0;
> +char *src_buf;
> +int rc;
> +
> +src = 0x8000 | s->regs[R_HASH_SRC];

Tricky. Also doesn't work on the AST2400 where SDRAM is based at 
0x4000?

Other than that it looks good to me.

Andrew



Re: [PATCH 2/2] aspeed: Integrate HACE

2021-03-08 Thread Andrew Jeffery



On Wed, 3 Mar 2021, at 17:33, Joel Stanley wrote:
> Add the hash and crypto engine model to the aspeed socs.
> 
> Signed-off-by: Joel Stanley 
> [ clg: documentation update ]
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Andrew Jeffery 



Re: [PATCH 1/2] hw: Model ASPEED's Hash and Crypto Engine

2021-03-08 Thread Andrew Jeffery



On Wed, 3 Mar 2021, at 17:33, Joel Stanley wrote:
> The HACE (Hash and Crpyto Engine) is a device that offloads MD5, SHA1,
> SHA2, RSA and other cryptographic algorithms.
> 
> This initial model implements a subset of the device's functionality;
> currently only direct access (non-scatter gather) hashing.
> 
> Signed-off-by: Joel Stanley 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/misc/aspeed_hace.h |  33 
>  hw/misc/aspeed_hace.c | 302 ++
>  hw/misc/meson.build   |   2 +-
>  3 files changed, 336 insertions(+), 1 deletion(-)
>  create mode 100644 include/hw/misc/aspeed_hace.h
>  create mode 100644 hw/misc/aspeed_hace.c
> 
> diff --git a/include/hw/misc/aspeed_hace.h 
> b/include/hw/misc/aspeed_hace.h
> new file mode 100644
> index ..e1fce670ef9e
> --- /dev/null
> +++ b/include/hw/misc/aspeed_hace.h
> @@ -0,0 +1,33 @@
> +/*
> + * ASPEED Hash and Crypto Engine
> + *
> + * Copyright (C) 2021 IBM Corp.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef ASPEED_HACE_H
> +#define ASPEED_HACE_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_ASPEED_HACE "aspeed.hace"
> +#define ASPEED_HACE(obj) OBJECT_CHECK(AspeedHACEState, (obj), 
> TYPE_ASPEED_HACE)
> +
> +#define ASPEED_HACE_NR_REGS (0x64 >> 2)

0x64 is the offset of the last defined register, so this should be (0x68 >> 2)

> +
> +typedef struct AspeedHACEState {
> +/*  */
> +SysBusDevice parent;
> +
> +/*< public >*/
> +MemoryRegion iomem;
> +qemu_irq irq;
> +
> +uint32_t regs[ASPEED_HACE_NR_REGS];
> +
> +MemoryRegion *dram_mr;
> +AddressSpace dram_as;
> +} AspeedHACEState;
> +
> +#endif /* _ASPEED_HACE_H_ */
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> new file mode 100644
> index ..0e402a0adea9
> --- /dev/null
> +++ b/hw/misc/aspeed_hace.c
> @@ -0,0 +1,302 @@
> +/*
> + * ASPEED Hash and Crypto Engine
> + *
> + * Copyright (C) 2021 IBM Corp.
> + *
> + * Joel Stanley 
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qemu/error-report.h"
> +#include "hw/misc/aspeed_hace.h"
> +#include "qapi/error.h"
> +#include "migration/vmstate.h"
> +#include "crypto/hash.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/irq.h"
> +
> +#define R_STATUS(0x1c / 4)
> +#define HASH_IRQBIT(9)
> +#define CRYPT_IRQ   BIT(12)
> +#define TAG_IRQ BIT(15)
> +
> +#define R_HASH_CMD  (0x30 / 4)
> +/* Hash algorithim selection */
> +#define  HASH_ALGO_MASK (BIT(4) | BIT(5) | BIT(6))

Hmm, feels GENMASK()-y, but looks like the tree is in a bit of a weird 
state in that respect:

$ git grep GENMASK
include/hw/usb/dwc2-regs.h:#define GSNPSID_ID_MASK  
GENMASK(31, 16)
include/standard-headers/asm-x86/kvm_para.h:#define KVM_ASYNC_PF_VEC_MASK   
GENMASK(7, 0)
$

> +#define  HASH_ALGO_MD5  0
> +#define  HASH_ALGO_SHA1 BIT(5)
> +#define  HASH_ALGO_SHA224   BIT(6)
> +#define  HASH_ALGO_SHA256   (BIT(4) | BIT(6))

Not something you need to fix necessarily, but it would feel more 
intuitive to me to order these MSB to LSB, so e.g. (BIT(6) | BIT(4)). 
That way I can "see" the value without having to reverse the bits.

> +#define  HASH_ALGO_SHA512_SERIES(BIT(5) | BIT(6))
> +/* SHA512 algorithim selection */
> +#define  SHA512_HASH_ALGO_MASK  (BIT(10) | BIT(11) | BIT(12))
> +#define  HASH_ALGO_SHA512_SHA5120
> +#define  HASH_ALGO_SHA512_SHA384BIT(10)
> +#define  HASH_ALGO_SHA512_SHA256BIT(11)
> +#define  HASH_ALGO_SHA512_SHA224(BIT(10) | BIT(11))
> +/* HMAC modes */
> +#define  HASH_HMAC_MASK (BIT(7) | BIT(8))
> +#define  HASH_DIGEST0
> +#define  HASH_DIGEST_HMAC   BIT(7)
> +#define  HASH_DIGEST_ACCUM  BIT(8)
> +#define  HASH_HMAC_KEY  (BIT(7) | BIT(8))
> +/* Cascscaed operation modes */
> +#define  HASH_ONLY  0
> +#define  HASH_ONLY2 BIT(0)
> +#define  HASH_CRYPT_THEN_HASH   BIT(1)
> +#define  HASH_HASH_THEN_CRYPT   (BIT(0) | BIT(1))
> +/* Other cmd bits */
> +#define  HASH_IRQ_ENBIT(9)
> +#define  HASH_SG_EN BIT(18)
> +
> +#define R_CRYPT_CMD (0x10 / 4)
> +
> +#define R_HASH_SRC  (0x20 / 4)
> +#define R_HASH_DEST (0x24 / 4)
> +#define R_HASH_SRC_LEN  (0x2c / 4)

In general, ordering the registers and fields in datasheet-order is 
helpful to me as a reviewer...

> +
> +static int do_hash_operation(AspeedHACEState *s, int algo)
> +{
> +hwaddr src, len, dest;
> +uint8_t *digest_buf = NULL;
> +size_t digest_len = 0;
> +char *src_buf;
> +int rc;
> +
> +src = s->regs[R_HASH_SRC];
> +len = s->regs[R_HASH_SRC_LEN];
> +dest = 

[PATCH v3 5/5] hw/misc: Model KCS devices in the Aspeed LPC controller

2021-03-01 Thread Andrew Jeffery
Keyboard-Controller-Style devices for IPMI purposes are exposed via LPC
IO cycles from the BMC to the host.

Expose support on the BMC side by implementing the usual MMIO
behaviours, and expose the ability to inspect the KCS registers in
"host" style by accessing QOM properties associated with each register.

The model caters to the IRQ style of both the AST2600 and the earlier
SoCs (AST2400 and AST2500). The AST2600 allocates an IRQ for each LPC
sub-device, while there is a single IRQ shared across all subdevices on
the AST2400 and AST2500.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed_ast2600.c  |  28 ++-
 hw/arm/aspeed_soc.c  |  24 ++-
 hw/misc/aspeed_lpc.c | 359 ++-
 include/hw/arm/aspeed_soc.h  |   1 +
 include/hw/misc/aspeed_lpc.h |  17 +-
 5 files changed, 424 insertions(+), 5 deletions(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 5a7b8ba81c92..4f83097e4a26 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -104,7 +104,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_ETH2]  = 3,
 [ASPEED_DEV_ETH3]  = 32,
 [ASPEED_DEV_ETH4]  = 33,
-
+[ASPEED_DEV_KCS]   = 138,   /* 138 -> 142 */
 };
 
 static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
@@ -477,8 +477,34 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 return;
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+
+/* Connect the LPC IRQ to the GIC. It is otherwise unused. */
 sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
+
+/*
+ * On the AST2600 LPC subdevice IRQs are connected straight to the GIC.
+ *
+ * LPC subdevice IRQ sources are offset from 1 because the LPC model caters
+ * to the AST2400 and AST2500. SoCs before the AST2600 have one LPC IRQ
+ * shared across the subdevices, and the shared IRQ output to the VIC is at
+ * offset 0.
+ */
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_1,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_1));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_2,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_2));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_3,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_3));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_4,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_4));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 4f098da437ac..057d053c8478 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -112,7 +112,6 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_DEV_WDT]= 27,
 [ASPEED_DEV_PWM]= 28,
 [ASPEED_DEV_LPC]= 8,
-[ASPEED_DEV_IBT]= 8, /* LPC */
 [ASPEED_DEV_I2C]= 12,
 [ASPEED_DEV_ETH1]   = 2,
 [ASPEED_DEV_ETH2]   = 3,
@@ -401,8 +400,31 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+
+/* Connect the LPC IRQ to the VIC */
 sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
+
+/*
+ * On the AST2400 and AST2500 the one LPC IRQ is shared between all of the
+ * subdevices. Connect the LPC subdevice IRQs to the LPC controller IRQ (by
+ * contrast, on the AST2600, the subdevice IRQs are connected straight to
+ * the GIC).
+ *
+ * LPC subdevice IRQ sources are offset from 1 because the shared IRQ 
output
+ * to the VIC is at offset 0.
+ */
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_1,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_1));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_2,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_2));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_3,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_3));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_4,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_4));
 }
 static Property aspeed_soc_properties[] = {
 DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEM

[PATCH v3 4/5] hw/misc: Add a basic Aspeed LPC controller model

2021-03-01 Thread Andrew Jeffery
From: Cédric Le Goater 

This is a very minimal framework to access registers which are used to
configure the AHB memory mapping of the flash chips on the LPC HC
Firmware address space.

Signed-off-by: Cédric Le Goater 
Signed-off-by: Andrew Jeffery 
---
 docs/system/arm/aspeed.rst   |   2 +-
 hw/arm/aspeed_ast2600.c  |  10 +++
 hw/arm/aspeed_soc.c  |  10 +++
 hw/misc/aspeed_lpc.c | 131 +++
 hw/misc/meson.build  |   7 +-
 include/hw/arm/aspeed_soc.h  |   2 +
 include/hw/misc/aspeed_lpc.h |  32 +
 7 files changed, 192 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/aspeed_lpc.c
 create mode 100644 include/hw/misc/aspeed_lpc.h

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index 690bada7842b..2f6fa8938d02 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -48,6 +48,7 @@ Supported devices
  * UART
  * Ethernet controllers
  * Front LEDs (PCA9552 on I2C bus)
+ * LPC Peripheral Controller (a subset of subdevices are supported)
 
 
 Missing devices
@@ -56,7 +57,6 @@ Missing devices
  * Coprocessor support
  * ADC (out of tree implementation)
  * PWM and Fan Controller
- * LPC Bus Controller
  * Slave GPIO Controller
  * Super I/O Controller
  * Hash/Crypto Engine
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 2125a96ef317..5a7b8ba81c92 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -211,6 +211,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
 
 object_initialize_child(obj, "emmc-controller.sdhci", >emmc.slots[0],
 TYPE_SYSBUS_SDHCI);
+
+object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
 }
 
 /*
@@ -469,6 +471,14 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>emmc), 0, sc->memmap[ASPEED_DEV_EMMC]);
 sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_EMMC));
+
+/* LPC */
+if (!sysbus_realize(SYS_BUS_DEVICE(>lpc), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 7eefd54ac07a..4f098da437ac 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -211,6 +211,8 @@ static void aspeed_soc_init(Object *obj)
 object_initialize_child(obj, "sdhci[*]", >sdhci.slots[i],
 TYPE_SYSBUS_SDHCI);
 }
+
+object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -393,6 +395,14 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 sc->memmap[ASPEED_DEV_SDHCI]);
 sysbus_connect_irq(SYS_BUS_DEVICE(>sdhci), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
+
+/* LPC */
+if (!sysbus_realize(SYS_BUS_DEVICE(>lpc), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
 }
 static Property aspeed_soc_properties[] = {
 DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
diff --git a/hw/misc/aspeed_lpc.c b/hw/misc/aspeed_lpc.c
new file mode 100644
index ..e668e985ff04
--- /dev/null
+++ b/hw/misc/aspeed_lpc.c
@@ -0,0 +1,131 @@
+/*
+ *  ASPEED LPC Controller
+ *
+ *  Copyright (C) 2017-2018 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_lpc.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+#define TO_REG(offset) ((offset) >> 2)
+
+#define HICR0TO_REG(0x00)
+#define HICR1TO_REG(0x04)
+#define HICR2TO_REG(0x08)
+#define HICR3TO_REG(0x0C)
+#define HICR4TO_REG(0x10)
+#define HICR5TO_REG(0x80)
+#define HICR6TO_REG(0x84)
+#define HICR7TO_REG(0x88)
+#define HICR8TO_REG(0x8C)
+
+static uint64_t aspeed_lpc_read(void *opaque, hwaddr offset, unsigned size)
+{
+AspeedLPCState *s = ASPEED_LPC(opaque);
+int reg = TO_REG(offset);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at 

[PATCH v3 1/5] hw/arm: ast2600: Force a multiple of 32 of IRQs for the GIC

2021-03-01 Thread Andrew Jeffery
This appears to be a requirement of the GIC model. The AST2600 allocates
197 GIC IRQs, which we will adjust shortly.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed_ast2600.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bf31ca351feb..bc0eeb058b24 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -65,7 +65,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 
 #define ASPEED_A7MPCORE_ADDR 0x4046
 
-#define ASPEED_SOC_AST2600_MAX_IRQ 128
+#define AST2600_MAX_IRQ 128
 
 /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
 static const int aspeed_soc_ast2600_irqmap[] = {
@@ -267,7 +267,7 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 object_property_set_int(OBJECT(>a7mpcore), "num-cpu", sc->num_cpus,
 _abort);
 object_property_set_int(OBJECT(>a7mpcore), "num-irq",
-ASPEED_SOC_AST2600_MAX_IRQ + GIC_INTERNAL,
+ROUND_UP(AST2600_MAX_IRQ + GIC_INTERNAL, 32),
 _abort);
 
 sysbus_realize(SYS_BUS_DEVICE(>a7mpcore), _abort);
-- 
2.27.0




[PATCH v3 3/5] hw/arm: ast2600: Correct the iBT interrupt ID

2021-03-01 Thread Andrew Jeffery
The AST2600 allocates distinct GIC IRQs for the LPC subdevices such as
the iBT device. Previously on the AST2400 and AST2500 the LPC subdevices
shared a single LPC IRQ.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed_ast2600.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 22fcb5b0edbe..2125a96ef317 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -98,7 +98,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_WDT]   = 24,
 [ASPEED_DEV_PWM]   = 44,
 [ASPEED_DEV_LPC]   = 35,
-[ASPEED_DEV_IBT]   = 35,/* LPC */
+[ASPEED_DEV_IBT]   = 143,
 [ASPEED_DEV_I2C]   = 110,   /* 110 -> 125 */
 [ASPEED_DEV_ETH1]  = 2,
 [ASPEED_DEV_ETH2]  = 3,
-- 
2.27.0




[PATCH v3 2/5] hw/arm: ast2600: Set AST2600_MAX_IRQ to value from datasheet

2021-03-01 Thread Andrew Jeffery
The datasheet says we have 197 IRQs allocated, and we need more than 128
to describe IRQs from LPC devices. Raise the value now to allow
modelling of the LPC devices.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed_ast2600.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bc0eeb058b24..22fcb5b0edbe 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -65,7 +65,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 
 #define ASPEED_A7MPCORE_ADDR 0x4046
 
-#define AST2600_MAX_IRQ 128
+#define AST2600_MAX_IRQ 197
 
 /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
 static const int aspeed_soc_ast2600_irqmap[] = {
-- 
2.27.0




[PATCH v3 0/5] aspeed: LPC peripheral controller devices

2021-03-01 Thread Andrew Jeffery
Hello,

This series adds support for some of the LPC[1] peripherals found in Aspeed BMC
SoCs.

[1] 
https://www.intel.com/content/dam/www/program/design/us/en/documents/low-pin-count-interface-specification.pdf

v3 fixes a copy/paste error hooking up the LPC IRQ for the AST2600, identified
off-list. I've tested exercised the eMMC path to confirm the fix. v2 of the
series can be found here:

https://lore.kernel.org/qemu-devel/20210301010610.355702-1-and...@aj.id.au/T/#mccf00fea21d955d74de39dbc49af8451b447ff54

BMCs typically provide a number of features to their host via LPC that include
but are not limited to:

1. Mapping LPC firmware cycles to BMC-controlled flash devices
2. UART(s) for system console routing
3. POST code routing
4. Keyboard-Controller-Style (KCS) IPMI devices
5. Block Transfer (BT) IPMI devices
6. A SuperIO controller for management of LPC devices and miscellaneous
   functionality

Specifically, this series adds basic support for functions 1 and 4 above,
handling the BMC firmware configuring the bridge mapping LPC firmware cycles
onto its AHB as well as support for four KCS devices.

Aspeed's LPC controller is not a straight-forward device by any stretch. It
contains at least the capabilities outlined above, in the sense that it's not
possible to cleanly separate the different functions into distinct MMIO
sub-regions: Registers for the various bits of functionality have the feel of
arbitrary placement with a nod to feature-creep and backwards compatibility.
Further, the conceptually coherent pieces of functionality often come with the
ability to issue interrupts, though for the AST2400 and AST2500 there is one
shared VIC IRQ for all LPC "subdevices". By contrast the AST2600 gives each
subdevice a distinct IRQ via the GIC.

All this combined leads to some complexity regarding the interrupts and handling
the MMIO accesses (in terms of mapping the access back to the function it's
affecting).

Finally, as a point of clarity, Aspeed BMCs also contain an LPC Host Controller
to drive the LPC bus. This series does not concern itself with the LPC Host
Controller function, only with a subset of the peripheral devices the BMC
presents to the host.

I've tested the series using a combination of the ast2600-evb, witherspoon-bmc
and romulus-bmc machines along with a set of recently-posted patches for
Linux[2].

Please review!

Andrew

[2] 
https://lore.kernel.org/openbmc/20210219142523.3464540-1-and...@aj.id.au/T/#m1e2029e7aa2be3056320e8d46b3b5b1539a776b4

Andrew Jeffery (4):
  hw/arm: ast2600: Force a multiple of 32 of IRQs for the GIC
  hw/arm: ast2600: Set AST2600_MAX_IRQ to value from datasheet
  hw/arm: ast2600: Correct the iBT interrupt ID
  hw/misc: Model KCS devices in the Aspeed LPC controller

Cédric Le Goater (1):
  hw/misc: Add a basic Aspeed LPC controller model

 docs/system/arm/aspeed.rst   |   2 +-
 hw/arm/aspeed_ast2600.c  |  44 +++-
 hw/arm/aspeed_soc.c  |  34 ++-
 hw/misc/aspeed_lpc.c | 486 +++
 hw/misc/meson.build  |   7 +-
 include/hw/arm/aspeed_soc.h  |   3 +
 include/hw/misc/aspeed_lpc.h |  47 
 7 files changed, 616 insertions(+), 7 deletions(-)
 create mode 100644 hw/misc/aspeed_lpc.c
 create mode 100644 include/hw/misc/aspeed_lpc.h


base-commit: 51db2d7cf26d05a961ec0ee0eb773594b32cc4a1
-- 
2.27.0




Re: [PATCH v2 4/5] hw/misc: Add a basic Aspeed LPC controller model

2021-03-01 Thread Andrew Jeffery



On Mon, 1 Mar 2021, at 11:36, Andrew Jeffery wrote:
> From: Cédric Le Goater 
> 
> This is a very minimal framework to access registers which are used to
> configure the AHB memory mapping of the flash chips on the LPC HC
> Firmware address space.
> 
> Signed-off-by: Cédric Le Goater 
> Signed-off-by: Andrew Jeffery 
> ---
>  docs/system/arm/aspeed.rst   |   2 +-
>  hw/arm/aspeed_ast2600.c  |  10 +++
>  hw/arm/aspeed_soc.c  |  10 +++
>  hw/misc/aspeed_lpc.c | 131 +++
>  hw/misc/meson.build  |   7 +-
>  include/hw/arm/aspeed_soc.h  |   2 +
>  include/hw/misc/aspeed_lpc.h |  32 +
>  7 files changed, 192 insertions(+), 2 deletions(-)
>  create mode 100644 hw/misc/aspeed_lpc.c
>  create mode 100644 include/hw/misc/aspeed_lpc.h
> 
> diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
> index 690bada7842b..2f6fa8938d02 100644
> --- a/docs/system/arm/aspeed.rst
> +++ b/docs/system/arm/aspeed.rst
> @@ -48,6 +48,7 @@ Supported devices
>   * UART
>   * Ethernet controllers
>   * Front LEDs (PCA9552 on I2C bus)
> + * LPC Peripheral Controller (a subset of subdevices are supported)
>  
>  
>  Missing devices
> @@ -56,7 +57,6 @@ Missing devices
>   * Coprocessor support
>   * ADC (out of tree implementation)
>   * PWM and Fan Controller
> - * LPC Bus Controller
>   * Slave GPIO Controller
>   * Super I/O Controller
>   * Hash/Crypto Engine
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index 2125a96ef317..60152de001e6 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -211,6 +211,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
>  
>  object_initialize_child(obj, "emmc-controller.sdhci", >emmc.slots[0],
>  TYPE_SYSBUS_SDHCI);
> +
> +object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
>  }
>  
>  /*
> @@ -469,6 +471,14 @@ static void aspeed_soc_ast2600_realize(DeviceState 
> *dev, Error **errp)
>  sysbus_mmio_map(SYS_BUS_DEVICE(>emmc), 0, 
> sc->memmap[ASPEED_DEV_EMMC]);
>  sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
> aspeed_soc_get_irq(s, ASPEED_DEV_EMMC));
> +
> +/* LPC */
> +if (!sysbus_realize(SYS_BUS_DEVICE(>lpc), errp)) {
> +return;
> +}
> +sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, 
> sc->memmap[ASPEED_DEV_LPC]);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
> +   aspeed_soc_get_irq(s, ASPEED_DEV_LPC));

Hah, this isn't right! We don't notice it wrt LPC devices because the 
LPC IRQ is unused right now, but it will impact the eMMC.

Let me do a v3.

Andrew



[PATCH v2 5/5] hw/misc: Model KCS devices in the Aspeed LPC controller

2021-02-28 Thread Andrew Jeffery
Keyboard-Controller-Style devices for IPMI purposes are exposed via LPC
IO cycles from the BMC to the host.

Expose support on the BMC side by implementing the usual MMIO
behaviours, and expose the ability to inspect the KCS registers in
"host" style by accessing QOM properties associated with each register.

The model caters to the IRQ style of both the AST2600 and the earlier
SoCs (AST2400 and AST2500). The AST2600 allocates an IRQ for each LPC
sub-device, while there is a single IRQ shared across all subdevices on
the AST2400 and AST2500.

Signed-off-by: Andrew Jeffery 
---
 hw/arm/aspeed_ast2600.c  |  28 ++-
 hw/arm/aspeed_soc.c  |  24 ++-
 hw/misc/aspeed_lpc.c | 359 ++-
 include/hw/arm/aspeed_soc.h  |   1 +
 include/hw/misc/aspeed_lpc.h |  17 +-
 5 files changed, 424 insertions(+), 5 deletions(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 60152de001e6..fd463775d281 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -104,7 +104,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_ETH2]  = 3,
 [ASPEED_DEV_ETH3]  = 32,
 [ASPEED_DEV_ETH4]  = 33,
-
+[ASPEED_DEV_KCS]   = 138,   /* 138 -> 142 */
 };
 
 static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
@@ -477,8 +477,34 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 return;
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+
+/* Connect the LPC IRQ to the GIC. It is otherwise unused. */
 sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
+
+/*
+ * On the AST2600 LPC subdevice IRQs are connected straight to the GIC.
+ *
+ * LPC subdevice IRQ sources are offset from 1 because the LPC model caters
+ * to the AST2400 and AST2500. SoCs before the AST2600 have one LPC IRQ
+ * shared across the subdevices, and the shared IRQ output to the VIC is at
+ * offset 0.
+ */
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_1,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_1));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_2,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_2));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_3,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_3));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_4,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_4));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 4f098da437ac..057d053c8478 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -112,7 +112,6 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_DEV_WDT]= 27,
 [ASPEED_DEV_PWM]= 28,
 [ASPEED_DEV_LPC]= 8,
-[ASPEED_DEV_IBT]= 8, /* LPC */
 [ASPEED_DEV_I2C]= 12,
 [ASPEED_DEV_ETH1]   = 2,
 [ASPEED_DEV_ETH2]   = 3,
@@ -401,8 +400,31 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+
+/* Connect the LPC IRQ to the VIC */
 sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
+
+/*
+ * On the AST2400 and AST2500 the one LPC IRQ is shared between all of the
+ * subdevices. Connect the LPC subdevice IRQs to the LPC controller IRQ (by
+ * contrast, on the AST2600, the subdevice IRQs are connected straight to
+ * the GIC).
+ *
+ * LPC subdevice IRQ sources are offset from 1 because the shared IRQ 
output
+ * to the VIC is at offset 0.
+ */
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_1,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_1));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_2,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_2));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_3,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_3));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_4,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_4));
 }
 static Property aspeed_soc_properties[] = {
 DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
diff --git a/hw/misc/a

[PATCH v2 3/5] hw/arm: ast2600: Correct the iBT interrupt ID

2021-02-28 Thread Andrew Jeffery
The AST2600 allocates distinct GIC IRQs for the LPC subdevices such as
the iBT device. Previously on the AST2400 and AST2500 the LPC subdevices
shared a single LPC IRQ.

Signed-off-by: Andrew Jeffery 
---
 hw/arm/aspeed_ast2600.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 22fcb5b0edbe..2125a96ef317 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -98,7 +98,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_WDT]   = 24,
 [ASPEED_DEV_PWM]   = 44,
 [ASPEED_DEV_LPC]   = 35,
-[ASPEED_DEV_IBT]   = 35,/* LPC */
+[ASPEED_DEV_IBT]   = 143,
 [ASPEED_DEV_I2C]   = 110,   /* 110 -> 125 */
 [ASPEED_DEV_ETH1]  = 2,
 [ASPEED_DEV_ETH2]  = 3,
-- 
2.27.0




[PATCH v2 4/5] hw/misc: Add a basic Aspeed LPC controller model

2021-02-28 Thread Andrew Jeffery
From: Cédric Le Goater 

This is a very minimal framework to access registers which are used to
configure the AHB memory mapping of the flash chips on the LPC HC
Firmware address space.

Signed-off-by: Cédric Le Goater 
Signed-off-by: Andrew Jeffery 
---
 docs/system/arm/aspeed.rst   |   2 +-
 hw/arm/aspeed_ast2600.c  |  10 +++
 hw/arm/aspeed_soc.c  |  10 +++
 hw/misc/aspeed_lpc.c | 131 +++
 hw/misc/meson.build  |   7 +-
 include/hw/arm/aspeed_soc.h  |   2 +
 include/hw/misc/aspeed_lpc.h |  32 +
 7 files changed, 192 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/aspeed_lpc.c
 create mode 100644 include/hw/misc/aspeed_lpc.h

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index 690bada7842b..2f6fa8938d02 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -48,6 +48,7 @@ Supported devices
  * UART
  * Ethernet controllers
  * Front LEDs (PCA9552 on I2C bus)
+ * LPC Peripheral Controller (a subset of subdevices are supported)
 
 
 Missing devices
@@ -56,7 +57,6 @@ Missing devices
  * Coprocessor support
  * ADC (out of tree implementation)
  * PWM and Fan Controller
- * LPC Bus Controller
  * Slave GPIO Controller
  * Super I/O Controller
  * Hash/Crypto Engine
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 2125a96ef317..60152de001e6 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -211,6 +211,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
 
 object_initialize_child(obj, "emmc-controller.sdhci", >emmc.slots[0],
 TYPE_SYSBUS_SDHCI);
+
+object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
 }
 
 /*
@@ -469,6 +471,14 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>emmc), 0, sc->memmap[ASPEED_DEV_EMMC]);
 sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_EMMC));
+
+/* LPC */
+if (!sysbus_realize(SYS_BUS_DEVICE(>lpc), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 7eefd54ac07a..4f098da437ac 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -211,6 +211,8 @@ static void aspeed_soc_init(Object *obj)
 object_initialize_child(obj, "sdhci[*]", >sdhci.slots[i],
 TYPE_SYSBUS_SDHCI);
 }
+
+object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -393,6 +395,14 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 sc->memmap[ASPEED_DEV_SDHCI]);
 sysbus_connect_irq(SYS_BUS_DEVICE(>sdhci), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
+
+/* LPC */
+if (!sysbus_realize(SYS_BUS_DEVICE(>lpc), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
 }
 static Property aspeed_soc_properties[] = {
 DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
diff --git a/hw/misc/aspeed_lpc.c b/hw/misc/aspeed_lpc.c
new file mode 100644
index ..e668e985ff04
--- /dev/null
+++ b/hw/misc/aspeed_lpc.c
@@ -0,0 +1,131 @@
+/*
+ *  ASPEED LPC Controller
+ *
+ *  Copyright (C) 2017-2018 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_lpc.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+#define TO_REG(offset) ((offset) >> 2)
+
+#define HICR0TO_REG(0x00)
+#define HICR1TO_REG(0x04)
+#define HICR2TO_REG(0x08)
+#define HICR3TO_REG(0x0C)
+#define HICR4TO_REG(0x10)
+#define HICR5TO_REG(0x80)
+#define HICR6TO_REG(0x84)
+#define HICR7TO_REG(0x88)
+#define HICR8TO_REG(0x8C)
+
+static uint64_t aspeed_lpc_read(void *opaque, hwaddr offset, unsigned size)
+{
+AspeedLPCState *s = ASPEED_LPC(opaque);
+int reg = TO_REG(offset);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at 

[PATCH v2 0/5] aspeed: LPC peripheral controller devices

2021-02-28 Thread Andrew Jeffery
Hello,

This series adds support for some of the LPC[1] peripherals found in Aspeed BMC
SoCs.

v2 addresses some minor feedback from Philippe and Cédric. v1 can be found here:

https://lore.kernel.org/qemu-devel/20210226065758.547824-1-and...@aj.id.au/T/#m28b4392d0672e85fbfaaf6565a2da2e82de1691d

BMCs typically provide a number of features to their host via LPC that include
but are not limited to:

1. Mapping LPC firmware cycles to BMC-controlled flash devices
2. UART(s) for system console routing
3. POST code routing
4. Keyboard-Controller-Style (KCS) IPMI devices
5. Block Transfer (BT) IPMI devices
6. A SuperIO controller for management of LPC devices and miscellaneous
   functionality

[1] 
https://www.intel.com/content/dam/www/program/design/us/en/documents/low-pin-count-interface-specification.pdf

Specifically, this series adds basic support for functions 1 and 4 above,
handling the BMC firmware configuring the bridge mapping LPC firmware cycles
onto its AHB as well as support for four KCS devices.

Aspeed's LPC controller is not a straight-forward device by any stretch. It
contains at least the capabilities outlined above, in the sense that it's not
possible to cleanly separate the different functions into distinct MMIO
sub-regions: Registers for the various bits of functionality have the feel of
arbitrary placement with a nod to feature-creep and backwards compatibility.
Further, the conceptually coherent pieces of functionality often come with the
ability to issue interrupts, though for the AST2400 and AST2500 there is one
shared VIC IRQ for all LPC "subdevices". By contrast the AST2600 gives each
subdevice a distinct IRQ via the GIC.

All this combined leads to some complexity regarding the interrupts and handling
the MMIO accesses (in terms of mapping the access back to the function it's
affecting).

Finally, as a point of clarity, Aspeed BMCs also contain an LPC Host Controller
to drive the LPC bus. This series does not concern itself with the LPC Host
Controller function, only with a subset of the peripheral devices the BMC
presents to the host.

I've tested the series using a combination of the ast2600-evb, witherspoon-bmc
and romulus-bmc machines along with a set of recently-posted patches for
Linux[2].

Please review!

Andrew

[2] 
https://lore.kernel.org/openbmc/20210219142523.3464540-1-and...@aj.id.au/T/#m1e2029e7aa2be3056320e8d46b3b5b1539a776b4

Andrew Jeffery (4):
  arm: ast2600: Force a multiple of 32 of IRQs for the GIC
  hw/arm: ast2600: Set AST2600_MAX_IRQ to value from datasheet
  hw/arm: ast2600: Correct the iBT interrupt ID
  hw/misc: Model KCS devices in the Aspeed LPC controller

Cédric Le Goater (1):
  hw/misc: Add a basic Aspeed LPC controller model

 docs/system/arm/aspeed.rst   |   2 +-
 hw/arm/aspeed_ast2600.c  |  44 +++-
 hw/arm/aspeed_soc.c  |  34 ++-
 hw/misc/aspeed_lpc.c | 486 +++
 hw/misc/meson.build  |   7 +-
 include/hw/arm/aspeed_soc.h  |   3 +
 include/hw/misc/aspeed_lpc.h |  47 
 7 files changed, 616 insertions(+), 7 deletions(-)
 create mode 100644 hw/misc/aspeed_lpc.c
 create mode 100644 include/hw/misc/aspeed_lpc.h


base-commit: 51db2d7cf26d05a961ec0ee0eb773594b32cc4a1
-- 
2.27.0




[PATCH v2 2/5] hw/arm: ast2600: Set AST2600_MAX_IRQ to value from datasheet

2021-02-28 Thread Andrew Jeffery
The datasheet says we have 197 IRQs allocated, and we need more than 128
to describe IRQs from LPC devices. Raise the value now to allow
modelling of the LPC devices.

Signed-off-by: Andrew Jeffery 
---
 hw/arm/aspeed_ast2600.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bc0eeb058b24..22fcb5b0edbe 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -65,7 +65,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 
 #define ASPEED_A7MPCORE_ADDR 0x4046
 
-#define AST2600_MAX_IRQ 128
+#define AST2600_MAX_IRQ 197
 
 /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
 static const int aspeed_soc_ast2600_irqmap[] = {
-- 
2.27.0




[PATCH v2 1/5] arm: ast2600: Force a multiple of 32 of IRQs for the GIC

2021-02-28 Thread Andrew Jeffery
This appears to be a requirement of the GIC model. The AST2600 allocates
197 GIC IRQs, which we will adjust shortly.

Signed-off-by: Andrew Jeffery 
---
 hw/arm/aspeed_ast2600.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bf31ca351feb..bc0eeb058b24 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -65,7 +65,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 
 #define ASPEED_A7MPCORE_ADDR 0x4046
 
-#define ASPEED_SOC_AST2600_MAX_IRQ 128
+#define AST2600_MAX_IRQ 128
 
 /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
 static const int aspeed_soc_ast2600_irqmap[] = {
@@ -267,7 +267,7 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 object_property_set_int(OBJECT(>a7mpcore), "num-cpu", sc->num_cpus,
 _abort);
 object_property_set_int(OBJECT(>a7mpcore), "num-irq",
-ASPEED_SOC_AST2600_MAX_IRQ + GIC_INTERNAL,
+ROUND_UP(AST2600_MAX_IRQ + GIC_INTERNAL, 32),
 _abort);
 
 sysbus_realize(SYS_BUS_DEVICE(>a7mpcore), _abort);
-- 
2.27.0




Re: [PATCH 1/4] arm: ast2600: Force a multiple of 32 of IRQs for the GIC

2021-02-28 Thread Andrew Jeffery



On Mon, 1 Mar 2021, at 09:37, Andrew Jeffery wrote:
> 
> 
> On Fri, 26 Feb 2021, at 19:26, Philippe Mathieu-Daudé wrote:
> > On 2/26/21 7:57 AM, Andrew Jeffery wrote:
> > > This appears to be a requirement of the GIC model.
> > 
> > If so this should be adjusted in the GIC or a15mp_priv_realize(),
> > not in each caller, isn't it?
> > 
> 
> Maybe, let me look into it. I'll clean it up in v2 if it makes sense.

So the current behaviour has been around since 2009, originating in 
41c1e2f54e6f ("arm: make sure that number of irqs can be represented in 
GICD_TYPER."). The GIC architecture specification says:

"The GICD_TYPER.ITLinesNumber field identifies the number of 
implemented GICD_ISENABLERns, and therefore the maximum number of SPIs 
that might be supported."

While the code says:

/* ITLinesNumber is represented as (N / 32) - 1 (see
 * gic_dist_readb) so this is an implementation imposed
 * restriction, not an architectural one:
 */
if (s->num_irq < 32 || (s->num_irq % 32)) {
error_setg(errp,
   "%d interrupt lines unsupported: not divisible by 
32",
   num_irq);
return;
}

My feeling is that it's better to be explicit in the models that are 
affected (i.e. leave the ROUND_UP() as I have it in this patch). This 
way if the implementation restriction is ever lifted, we know which 
models we can clean up. I won't be reworking the GIC to remove the 
restriction in this series, so unless you have a particularly strong 
preference/justification for the implicit ROUND_UP(), I plan to leave 
it as is.

Cheers,

Andrew



Re: [PATCH 4/4] hw/misc: Model KCS devices in the Aspeed LPC controller

2021-02-28 Thread Andrew Jeffery



On Fri, 26 Feb 2021, at 20:21, Cédric Le Goater wrote:
> On 2/26/21 7:57 AM, Andrew Jeffery wrote:
> > Keyboard-Controller-Style devices for IPMI purposes are exposed via LPC
> > IO cycles from the BMC to the host.
> > 
> > Expose support on the BMC side by implementing the usual MMIO
> > behaviours, and expose the ability to inspect the KCS registers in
> > "host" style by accessing QOM properties associated with each register.
> > 
> > The model caters to the IRQ style of both the AST2600 and the earlier
> > SoCs (AST2400 and AST2500). The AST2600 allocates an IRQ for each LPC
> > sub-device, while there is a single IRQ shared across all subdevices on
> > the AST2400 and AST2500.
> > 
> > Signed-off-by: Andrew Jeffery 
> > ---
> >  hw/arm/aspeed_ast2600.c  |  28 ++-
> >  hw/arm/aspeed_soc.c  |  24 ++-
> >  hw/misc/aspeed_lpc.c | 354 +++
> >  include/hw/arm/aspeed_soc.h  |   1 +
> >  include/hw/misc/aspeed_lpc.h |  17 +-
> >  5 files changed, 421 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> > index 60152de001e6..fd463775d281 100644
> > --- a/hw/arm/aspeed_ast2600.c
> > +++ b/hw/arm/aspeed_ast2600.c
> > @@ -104,7 +104,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
> >  [ASPEED_DEV_ETH2]  = 3,
> >  [ASPEED_DEV_ETH3]  = 32,
> >  [ASPEED_DEV_ETH4]  = 33,
> > -
> > +[ASPEED_DEV_KCS]   = 138,   /* 138 -> 142 */
> >  };
> >  
> >  static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
> > @@ -477,8 +477,34 @@ static void aspeed_soc_ast2600_realize(DeviceState 
> > *dev, Error **errp)
> >  return;
> >  }
> >  sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, 
> > sc->memmap[ASPEED_DEV_LPC]);
> > +
> > +/* Connect the LPC IRQ to the GIC. It is otherwise unused. */
> >  sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
> > aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
> > +
> > +/*
> > + * On the AST2600 LPC subdevice IRQs are connected straight to the GIC.
> > + *
> > + * LPC subdevice IRQ sources are offset from 1 because the LPC model 
> > caters
> > + * to the AST2400 and AST2500. SoCs before the AST2600 have one LPC IRQ
> > + * shared across the subdevices, and the shared IRQ output to the VIC 
> > is at
> > + * offset 0.
> > + */
> > +sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_1,
> > +   qdev_get_gpio_in(DEVICE(>a7mpcore),
> > +sc->irqmap[ASPEED_DEV_KCS] + 
> > aspeed_lpc_kcs_1));
> > +
> > +sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_2,
> > +   qdev_get_gpio_in(DEVICE(>a7mpcore),
> > +sc->irqmap[ASPEED_DEV_KCS] + 
> > aspeed_lpc_kcs_2));
> > +
> > +sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_3,
> > +   qdev_get_gpio_in(DEVICE(>a7mpcore),
> > +sc->irqmap[ASPEED_DEV_KCS] + 
> > aspeed_lpc_kcs_3));
> > +
> > +sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_4,
> > +   qdev_get_gpio_in(DEVICE(>a7mpcore),
> > +sc->irqmap[ASPEED_DEV_KCS] + 
> > aspeed_lpc_kcs_4));
> >  }
> >  
> >  static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
> > diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> > index 4f098da437ac..057d053c8478 100644
> > --- a/hw/arm/aspeed_soc.c
> > +++ b/hw/arm/aspeed_soc.c
> > @@ -112,7 +112,6 @@ static const int aspeed_soc_ast2400_irqmap[] = {
> >  [ASPEED_DEV_WDT]= 27,
> >  [ASPEED_DEV_PWM]= 28,
> >  [ASPEED_DEV_LPC]= 8,
> > -[ASPEED_DEV_IBT]= 8, /* LPC */
> >  [ASPEED_DEV_I2C]= 12,
> >  [ASPEED_DEV_ETH1]   = 2,
> >  [ASPEED_DEV_ETH2]   = 3,
> > @@ -401,8 +400,31 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
> > **errp)
> >  return;
> >  }
> >  sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, 
> > sc->memmap[ASPEED_DEV_LPC]);
> > +
> > +/* Connect the LPC IRQ to the VIC */
> >  sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
> > aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
> > +
> > +/*

Re: [PATCH 2/4] arm: ast2600: Fix iBT IRQ ID

2021-02-28 Thread Andrew Jeffery



On Fri, 26 Feb 2021, at 19:28, Philippe Mathieu-Daudé wrote:
> On 2/26/21 7:57 AM, Andrew Jeffery wrote:
> > The AST2600 allocates individual GIC IRQ lines for the LPC sub-devices.
> > This is a contrast to the AST2400 and AST2500 which use one shared VIC
> > IRQ line for the LPC sub-devices. Switch the iBT device to use the
> > GIC IRQ ID documented in the datasheet.
> 
> [*]
> 
> > 
> > While we're here, set the number of IRQs to the allocated number of IRQs
> > in the datasheet.
> 
> Please do one change per patch. This would be the first change,
> and [*] is the second.

Given that I had to change the current value to support the iBT device 
I figured it would be fine in the same patch, but sure, I can split 
this out in v2.

Andrew



Re: [PATCH 1/4] arm: ast2600: Force a multiple of 32 of IRQs for the GIC

2021-02-28 Thread Andrew Jeffery



On Fri, 26 Feb 2021, at 19:26, Philippe Mathieu-Daudé wrote:
> On 2/26/21 7:57 AM, Andrew Jeffery wrote:
> > This appears to be a requirement of the GIC model.
> 
> If so this should be adjusted in the GIC or a15mp_priv_realize(),
> not in each caller, isn't it?
> 

Maybe, let me look into it. I'll clean it up in v2 if it makes sense.

Cheers,

Andrew



[PATCH 4/4] hw/misc: Model KCS devices in the Aspeed LPC controller

2021-02-25 Thread Andrew Jeffery
Keyboard-Controller-Style devices for IPMI purposes are exposed via LPC
IO cycles from the BMC to the host.

Expose support on the BMC side by implementing the usual MMIO
behaviours, and expose the ability to inspect the KCS registers in
"host" style by accessing QOM properties associated with each register.

The model caters to the IRQ style of both the AST2600 and the earlier
SoCs (AST2400 and AST2500). The AST2600 allocates an IRQ for each LPC
sub-device, while there is a single IRQ shared across all subdevices on
the AST2400 and AST2500.

Signed-off-by: Andrew Jeffery 
---
 hw/arm/aspeed_ast2600.c  |  28 ++-
 hw/arm/aspeed_soc.c  |  24 ++-
 hw/misc/aspeed_lpc.c | 354 +++
 include/hw/arm/aspeed_soc.h  |   1 +
 include/hw/misc/aspeed_lpc.h |  17 +-
 5 files changed, 421 insertions(+), 3 deletions(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 60152de001e6..fd463775d281 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -104,7 +104,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_ETH2]  = 3,
 [ASPEED_DEV_ETH3]  = 32,
 [ASPEED_DEV_ETH4]  = 33,
-
+[ASPEED_DEV_KCS]   = 138,   /* 138 -> 142 */
 };
 
 static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
@@ -477,8 +477,34 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 return;
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+
+/* Connect the LPC IRQ to the GIC. It is otherwise unused. */
 sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
+
+/*
+ * On the AST2600 LPC subdevice IRQs are connected straight to the GIC.
+ *
+ * LPC subdevice IRQ sources are offset from 1 because the LPC model caters
+ * to the AST2400 and AST2500. SoCs before the AST2600 have one LPC IRQ
+ * shared across the subdevices, and the shared IRQ output to the VIC is at
+ * offset 0.
+ */
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_1,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_1));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_2,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_2));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_3,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_3));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_4,
+   qdev_get_gpio_in(DEVICE(>a7mpcore),
+sc->irqmap[ASPEED_DEV_KCS] + 
aspeed_lpc_kcs_4));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 4f098da437ac..057d053c8478 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -112,7 +112,6 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_DEV_WDT]= 27,
 [ASPEED_DEV_PWM]= 28,
 [ASPEED_DEV_LPC]= 8,
-[ASPEED_DEV_IBT]= 8, /* LPC */
 [ASPEED_DEV_I2C]= 12,
 [ASPEED_DEV_ETH1]   = 2,
 [ASPEED_DEV_ETH2]   = 3,
@@ -401,8 +400,31 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+
+/* Connect the LPC IRQ to the VIC */
 sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
+
+/*
+ * On the AST2400 and AST2500 the one LPC IRQ is shared between all of the
+ * subdevices. Connect the LPC subdevice IRQs to the LPC controller IRQ (by
+ * contrast, on the AST2600, the subdevice IRQs are connected straight to
+ * the GIC).
+ *
+ * LPC subdevice IRQ sources are offset from 1 because the shared IRQ 
output
+ * to the VIC is at offset 0.
+ */
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_1,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_1));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_2,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_2));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_3,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_3));
+
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_kcs_4,
+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_kcs_4));
 }
 static Property aspeed_soc_properties[] = {
 DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
diff --git a/hw/misc/a

[PATCH 3/4] hw/misc: Add a basic Aspeed LPC controller model

2021-02-25 Thread Andrew Jeffery
From: Cédric Le Goater 

This is a very minimal framework to access registers which are used to
configure the AHB memory mapping of the flash chips on the LPC HC
Firmware address space.

Signed-off-by: Cédric Le Goater 
Signed-off-by: Andrew Jeffery 
---
 docs/system/arm/aspeed.rst   |   2 +-
 hw/arm/aspeed_ast2600.c  |  10 +++
 hw/arm/aspeed_soc.c  |  10 +++
 hw/misc/aspeed_lpc.c | 131 +++
 hw/misc/meson.build  |   7 +-
 include/hw/arm/aspeed_soc.h  |   2 +
 include/hw/misc/aspeed_lpc.h |  32 +
 7 files changed, 192 insertions(+), 2 deletions(-)
 create mode 100644 hw/misc/aspeed_lpc.c
 create mode 100644 include/hw/misc/aspeed_lpc.h

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index 690bada7842b..2f6fa8938d02 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -48,6 +48,7 @@ Supported devices
  * UART
  * Ethernet controllers
  * Front LEDs (PCA9552 on I2C bus)
+ * LPC Peripheral Controller (a subset of subdevices are supported)
 
 
 Missing devices
@@ -56,7 +57,6 @@ Missing devices
  * Coprocessor support
  * ADC (out of tree implementation)
  * PWM and Fan Controller
- * LPC Bus Controller
  * Slave GPIO Controller
  * Super I/O Controller
  * Hash/Crypto Engine
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 2125a96ef317..60152de001e6 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -211,6 +211,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
 
 object_initialize_child(obj, "emmc-controller.sdhci", >emmc.slots[0],
 TYPE_SYSBUS_SDHCI);
+
+object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
 }
 
 /*
@@ -469,6 +471,14 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>emmc), 0, sc->memmap[ASPEED_DEV_EMMC]);
 sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_EMMC));
+
+/* LPC */
+if (!sysbus_realize(SYS_BUS_DEVICE(>lpc), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>emmc), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 7eefd54ac07a..4f098da437ac 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -211,6 +211,8 @@ static void aspeed_soc_init(Object *obj)
 object_initialize_child(obj, "sdhci[*]", >sdhci.slots[i],
 TYPE_SYSBUS_SDHCI);
 }
+
+object_initialize_child(obj, "lpc", >lpc, TYPE_ASPEED_LPC);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -393,6 +395,14 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 sc->memmap[ASPEED_DEV_SDHCI]);
 sysbus_connect_irq(SYS_BUS_DEVICE(>sdhci), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
+
+/* LPC */
+if (!sysbus_realize(SYS_BUS_DEVICE(>lpc), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
 }
 static Property aspeed_soc_properties[] = {
 DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
diff --git a/hw/misc/aspeed_lpc.c b/hw/misc/aspeed_lpc.c
new file mode 100644
index ..e668e985ff04
--- /dev/null
+++ b/hw/misc/aspeed_lpc.c
@@ -0,0 +1,131 @@
+/*
+ *  ASPEED LPC Controller
+ *
+ *  Copyright (C) 2017-2018 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_lpc.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+
+#define TO_REG(offset) ((offset) >> 2)
+
+#define HICR0TO_REG(0x00)
+#define HICR1TO_REG(0x04)
+#define HICR2TO_REG(0x08)
+#define HICR3TO_REG(0x0C)
+#define HICR4TO_REG(0x10)
+#define HICR5TO_REG(0x80)
+#define HICR6TO_REG(0x84)
+#define HICR7TO_REG(0x88)
+#define HICR8TO_REG(0x8C)
+
+static uint64_t aspeed_lpc_read(void *opaque, hwaddr offset, unsigned size)
+{
+AspeedLPCState *s = ASPEED_LPC(opaque);
+int reg = TO_REG(offset);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at 

[PATCH 1/4] arm: ast2600: Force a multiple of 32 of IRQs for the GIC

2021-02-25 Thread Andrew Jeffery
This appears to be a requirement of the GIC model. The AST2600 allocates
197 GIC IRQs, which we will adjust shortly.

Signed-off-by: Andrew Jeffery 
---
 hw/arm/aspeed_ast2600.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bf31ca351feb..bc0eeb058b24 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -65,7 +65,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 
 #define ASPEED_A7MPCORE_ADDR 0x4046
 
-#define ASPEED_SOC_AST2600_MAX_IRQ 128
+#define AST2600_MAX_IRQ 128
 
 /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
 static const int aspeed_soc_ast2600_irqmap[] = {
@@ -267,7 +267,7 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 object_property_set_int(OBJECT(>a7mpcore), "num-cpu", sc->num_cpus,
 _abort);
 object_property_set_int(OBJECT(>a7mpcore), "num-irq",
-ASPEED_SOC_AST2600_MAX_IRQ + GIC_INTERNAL,
+ROUND_UP(AST2600_MAX_IRQ + GIC_INTERNAL, 32),
 _abort);
 
 sysbus_realize(SYS_BUS_DEVICE(>a7mpcore), _abort);
-- 
2.27.0




[PATCH 2/4] arm: ast2600: Fix iBT IRQ ID

2021-02-25 Thread Andrew Jeffery
The AST2600 allocates individual GIC IRQ lines for the LPC sub-devices.
This is a contrast to the AST2400 and AST2500 which use one shared VIC
IRQ line for the LPC sub-devices. Switch the iBT device to use the
GIC IRQ ID documented in the datasheet.

While we're here, set the number of IRQs to the allocated number of IRQs
in the datasheet.

Signed-off-by: Andrew Jeffery 
---
 hw/arm/aspeed_ast2600.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bc0eeb058b24..2125a96ef317 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -65,7 +65,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 
 #define ASPEED_A7MPCORE_ADDR 0x4046
 
-#define AST2600_MAX_IRQ 128
+#define AST2600_MAX_IRQ 197
 
 /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
 static const int aspeed_soc_ast2600_irqmap[] = {
@@ -98,7 +98,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_WDT]   = 24,
 [ASPEED_DEV_PWM]   = 44,
 [ASPEED_DEV_LPC]   = 35,
-[ASPEED_DEV_IBT]   = 35,/* LPC */
+[ASPEED_DEV_IBT]   = 143,
 [ASPEED_DEV_I2C]   = 110,   /* 110 -> 125 */
 [ASPEED_DEV_ETH1]  = 2,
 [ASPEED_DEV_ETH2]  = 3,
-- 
2.27.0




[PATCH 0/4] aspeed: LPC peripheral controller devices

2021-02-25 Thread Andrew Jeffery
Hello,

This series adds support for some of the LPC[1] peripherals found in Aspeed BMC
SoCs. BMCs typically provide a number of features to their host via LPC that
include but are not limited to:

1. Mapping LPC firmware cycles to BMC-controlled flash devices
2. UART(s) for system console routing
3. POST code routing
4. Keyboard-Controller-Style (KCS) IPMI devices
5. Block Transfer (BT) IPMI devices
6. A SuperIO controller for management of LPC devices and miscellaneous
   functionality

[1] 
https://www.intel.com/content/dam/www/program/design/us/en/documents/low-pin-count-interface-specification.pdf

Specifically, this series adds basic support for functions 1 and 4 above,
handling the BMC firmware configuring the bridge mapping LPC firmware cycles
onto its AHB as well as support for four KCS devices.

Aspeed's LPC controller is not a straight-forward device by any stretch. It
contains at least the capabilities outlined above, in the sense that it's not
possible to cleanly separate the different functions into distinct MMIO
sub-regions: Registers for the various bits of functionality have the feel of
arbitrary placement with a nod to feature-creep and backwards compatibility.
Further, the conceptually coherent pieces of functionality often come with the
ability to issue interrupts, though for the AST2400 and AST2500 there is one
shared VIC IRQ for all LPC "subdevices". By contrast the AST2600 gives each
subdevice a distinct IRQ via the GIC.

All this combined leads to some complexity regarding the interrupts and handling
the MMIO accesses (in terms of mapping the access back to the function it's
affecting).

Finally, as a point of clarity, Aspeed BMCs also contain an LPC Host Controller
to master the LPC bus. This series does not concern itself with the LPC Host
Controller function, only with a subset of the peripheral devices the BMC
presents to the host.

I've tested the series using a combination of the ast2600-evb, witherspoon-bmc
and romulus-bmc machines along with a set of recently-posted patches for
Linux[2].

Please review!

Andrew

[2] 
https://lore.kernel.org/openbmc/20210219142523.3464540-1-and...@aj.id.au/T/#m1e2029e7aa2be3056320e8d46b3b5b1539a776b4

Andrew Jeffery (3):
  arm: ast2600: Force a multiple of 32 of IRQs for the GIC
  arm: ast2600: Fix iBT IRQ ID
  hw/misc: Model KCS devices in the Aspeed LPC controller

Cédric Le Goater (1):
  hw/misc: Add a basic Aspeed LPC controller model

 docs/system/arm/aspeed.rst   |   2 +-
 hw/arm/aspeed_ast2600.c  |  44 +++-
 hw/arm/aspeed_soc.c  |  34 ++-
 hw/misc/aspeed_lpc.c | 485 +++
 hw/misc/meson.build  |   7 +-
 include/hw/arm/aspeed_soc.h  |   3 +
 include/hw/misc/aspeed_lpc.h |  47 
 7 files changed, 615 insertions(+), 7 deletions(-)
 create mode 100644 hw/misc/aspeed_lpc.c
 create mode 100644 include/hw/misc/aspeed_lpc.h


base-commit: 51db2d7cf26d05a961ec0ee0eb773594b32cc4a1
-- 
2.27.0




Re: [PATCH 4/7] ppc/pnv: Simplify pnv_bmc_create()

2021-01-31 Thread Andrew Jeffery



On Fri, 29 Jan 2021, at 19:09, Cédric Le Goater wrote:
> On 1/28/21 11:40 PM, David Gibson wrote:
> > On Thu, Jan 28, 2021 at 08:46:01AM +0100, Cédric Le Goater wrote:
> >> On 1/28/21 1:46 AM, Joel Stanley wrote:
> >>> On Tue, 26 Jan 2021 at 17:14, Cédric Le Goater  wrote:
> 
>  and reuse pnv_bmc_set_pnor() to share the setting of the PNOR.
> 
>  Signed-off-by: Cédric Le Goater 
>  ---
>   hw/ppc/pnv_bmc.c | 7 +--
>   1 file changed, 1 insertion(+), 6 deletions(-)
> 
>  diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
>  index 67ebb16c4d5f..86d16b493539 100644
>  --- a/hw/ppc/pnv_bmc.c
>  +++ b/hw/ppc/pnv_bmc.c
>  @@ -260,13 +260,8 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
>   Object *obj;
> 
>   obj = object_new(TYPE_IPMI_BMC_SIMULATOR);
>  -object_ref(OBJECT(pnor));
>  -object_property_add_const_link(obj, "pnor", OBJECT(pnor));
> >>>
> >>> I assume it's ok to move the link set to after the realise of the BMC 
> >>> object?
> >>  
> >>
> >> When 2 objects need to be linked, one has to be realized first. 
> >> I suppose this is why it is allowed but I am not expert in that area. 
> >>
> >> Greg  ?
> >>
> >> That was the case already when defining a "ipmi-bmc-sim" device on the 
> >> command line.
> > 
> > Well, the other thing here is that the IPMI_BMC_SIMULATOR isn't a
> > POWER specific object, and doesn't actually know anything about pnor,
> > so it never looks at that property.  Do we even need it?
> 
> It does through hiomap_cmd() which handles HIOMAP commands related 
> to the PNOR. The link was introduced to remove a reference to the 
> global machine (qdev_get_machine()). The PNOR device is instantiated 
> at the machine level but conceptually, this is incorrect. 
> 
> The PNOR is a device controlled by the BMC and accessed by the host 
> through a mapping on the LPC FW address space. It used to be controlled 
> from the host also, through the iLPC2AHB device and mboxes, but these 
> "doors" were closed sometime ago.

Right, so rehashing what Cédric said about the context for the PNOR and IPMI:

On PowerNV platforms, the host firmware accesses the data in the PNOR by 
sending commands over IPMI to the BMC to change the mappings in the LPC FW 
space. HIOMAP (Host I/O Map)[1] is the name of the little spec/protocol that 
defines the layout of data in the FW space and the commands and ABI for 
manipulating the mappings.

[1] https://github.com/openbmc/hiomapd/blob/master/Documentation/protocol.md

It's all terrible, but IPMI was the most well-trodden path I had at my disposal 
for improving the security of the (Aspeed) BMCs' hardware configuration for 
Power platform designs. From BMC reset the host has unrestricted access to the 
BMC's AHB via bridges on the LPC and PCIe buses until the BMC firmware disables 
them. Leaving the bridges enabled is not great for security or stability of the 
BMC firmware, so this meant cooking up some magic to allow the host to write 
back to the PNOR (owned by the BMC as Cédric mentions above) without exposing 
the BMC in unacceptable ways.

Andrew



Re: [PATCH] hw/arm/aspeed: Map the UART5 device unconditionally

2020-09-30 Thread Andrew Jeffery



On Wed, 30 Sep 2020, at 19:37, Cédric Le Goater wrote:
> On 9/30/20 7:29 AM, Andrew Jeffery wrote:
> > 
> > 
> > On Fri, 18 Sep 2020, at 02:33, Cédric Le Goater wrote:
> >> On 9/17/20 6:57 PM, Philippe Mathieu-Daudé wrote:
> >>> On 9/16/20 7:51 AM, Cédric Le Goater wrote:
> >>>> On 9/15/20 7:23 PM, Philippe Mathieu-Daudé wrote:
> >>>>> ping?
> >>>>
> >>>> It's reviewed : 
> >>>>
> >>>>   
> >>>> http://patchwork.ozlabs.org/project/qemu-devel/patch/20200905212415.760452-1-f4...@amsat.org/
> >>>>
> >>>
> >>> Yes I know :) This is part of my routine to check if a
> >>> patch hasn't been confirmed to be queued 1 week after the
> >>> last review, to ping the maintainer (because some
> >>> automatically flush patches older than 1month in their
> >>> mailbox).
> >>
> >> ooh. That's brutal.
> >>
> >>>> I will send a PR when I have more patches.
> >>>
> >>> Ah OK. I didn't know you would keep merging the Aspeed
> >>> patches. Since this was a single patch, I thought it would
> >>> go via the usual qemu-arm queue from Peter.
> >>
> >> sure. It could also. Fine with me. I have only three for the
> >> moment. 
> >>
> >>> No rush, I just wanted to be sure the patch was not lost.
> >>> Also, once a patch is queued, I understand it is the
> >>> maintainer responsibility to keep rebasing the patch
> >>> queued.
> >>
> >> yes. I know. I have been taking care of Andrew's ADC patches 
> >> since 2017 ... cough cough :)
> > 
> > Agh!
> 
> Does that mean "I will work on it !" ? :)

I'll see what I can do, I've recently started to rearrange my task queue.

Andrew



Re: [PATCH] hw/arm/aspeed: Map the UART5 device unconditionally

2020-09-29 Thread Andrew Jeffery



On Fri, 18 Sep 2020, at 02:33, Cédric Le Goater wrote:
> On 9/17/20 6:57 PM, Philippe Mathieu-Daudé wrote:
> > On 9/16/20 7:51 AM, Cédric Le Goater wrote:
> >> On 9/15/20 7:23 PM, Philippe Mathieu-Daudé wrote:
> >>> ping?
> >>
> >> It's reviewed : 
> >>
> >>   
> >> http://patchwork.ozlabs.org/project/qemu-devel/patch/20200905212415.760452-1-f4...@amsat.org/
> >>
> > 
> > Yes I know :) This is part of my routine to check if a
> > patch hasn't been confirmed to be queued 1 week after the
> > last review, to ping the maintainer (because some
> > automatically flush patches older than 1month in their
> > mailbox).
> 
> ooh. That's brutal.
> 
> >> I will send a PR when I have more patches.
> > 
> > Ah OK. I didn't know you would keep merging the Aspeed
> > patches. Since this was a single patch, I thought it would
> > go via the usual qemu-arm queue from Peter.
> 
> sure. It could also. Fine with me. I have only three for the
> moment. 
> 
> > No rush, I just wanted to be sure the patch was not lost.
> > Also, once a patch is queued, I understand it is the
> > maintainer responsibility to keep rebasing the patch
> > queued.
> 
> yes. I know. I have been taking care of Andrew's ADC patches 
> since 2017 ... cough cough :)

Agh!



Re: [PATCH v2] ftgmac100: fix dblac write test

2020-07-05 Thread Andrew Jeffery



On Sun, 28 Jun 2020, at 23:56, erik-smit wrote:
> The test of the write of the dblac register was testing the old value
> instead of the new value. This would accept the write of an invalid value
> but subsequently refuse any following valid writes.
> 
> Signed-off-by: erik-smit 
> ---
> Changes since v1:
> 
> Changed %ld to HWADDR_PRIx to fix building on mingw

Bit of a nitpick, but the type of the value argument is uint64_t, so shouldn't 
the result of the expression captured by FTGMAC100_DBLAC_TXDES_SIZE() and 
FTGMAC100_DBLAC_RXDES_SIZE() be printed with a straight PRIx64 rather than 
HWADDR_PRIx?

Otherwise the change seems sensible, so:

Reviewed-by: Andrew Jeffery 



Re: [PATCH v2 1/5] hw/i2c/aspeed_i2c: Simplify aspeed_i2c_get_bus()

2020-07-05 Thread Andrew Jeffery



On Mon, 6 Jul 2020, at 08:11, Philippe Mathieu-Daudé wrote:
> All the callers of aspeed_i2c_get_bus() have a AspeedI2CState and
> cast it to a DeviceState with DEVICE(), then aspeed_i2c_get_bus()
> cast the DeviceState to an AspeedI2CState with ASPEED_I2C()...
> 
> Simplify aspeed_i2c_get_bus() callers by using AspeedI2CState
> argument.
> 
> Reviewed-by: Markus Armbruster 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Andrew Jeffery 



Re: [PATCH 7/7] hw/watchdog/wdt_aspeed: Reduce timer precision to micro-second

2020-06-22 Thread Andrew Jeffery



On Mon, 22 Jun 2020, at 18:13, Philippe Mathieu-Daudé wrote:
> On 6/22/20 2:21 AM, Andrew Jeffery wrote:
> > On Wed, 17 Jun 2020, at 13:11, Philippe Mathieu-Daudé wrote:
> >> Hi Andrew,
> >>
> >> On 6/17/20 3:18 AM, Andrew Jeffery wrote:
> >>> On Tue, 16 Jun 2020, at 17:21, Philippe Mathieu-Daudé wrote:
> >>>> The current implementation uses nano-second precision, while
> >>>> the watchdog can not be more precise than a micro-second.
> >>>
> >>> What's the basis for this assertion? It's true for the AST2500 and 
> >>> AST2600, but 
> >>> the AST2400 can run the watchdog from either a 1MHz clock source or the 
> >>> APB 
> >>> clock (which must be at least 16.5MHz on palmetto). The reset state on the
> >>> AST2400 configures the watchdog for the APB clock rate.
> >>>
> >>> The Linux driver will eventually configure the watchdog for 1MHz mode
> >>> regardless so perhaps the AST2400 reset state is a bit of a corner case, 
> >>> but
> >>> I feel the assertion should be watered down a bit?
> >>
> >> What about this description?
> >>
> >> "The current implementation uses nano-second precision, but
> >>  is not more precise than micro-second precision.
> >>  Simplify by using a micro-second based timer.
> >>  Rename the timer 'timer_us' to have the unit explicit."
> > 
> > So is this a limitation of QEMUTimer? I was establishing that the hardware 
> > can 
> > operate at greater than 1 micro-second precision.
> 
> No, I misread your comment about the AST2400 timer which can run
> at more than 1Mhz.
> 
> The QEMUTimer doesn't have a such limitation; this patch
> aimed to simplify the code for reviewers, but you proved
> it incorrect, so let's disregard it.
> 
> Thanks for your careful review!

Ah, great, I was wondering where my misunderstanding was.

Thanks for clearing that up.

Andrew



Re: [PATCH 7/7] hw/watchdog/wdt_aspeed: Reduce timer precision to micro-second

2020-06-21 Thread Andrew Jeffery



On Wed, 17 Jun 2020, at 13:11, Philippe Mathieu-Daudé wrote:
> Hi Andrew,
> 
> On 6/17/20 3:18 AM, Andrew Jeffery wrote:
> > On Tue, 16 Jun 2020, at 17:21, Philippe Mathieu-Daudé wrote:
> >> The current implementation uses nano-second precision, while
> >> the watchdog can not be more precise than a micro-second.
> > 
> > What's the basis for this assertion? It's true for the AST2500 and AST2600, 
> > but 
> > the AST2400 can run the watchdog from either a 1MHz clock source or the APB 
> > clock (which must be at least 16.5MHz on palmetto). The reset state on the
> > AST2400 configures the watchdog for the APB clock rate.
> > 
> > The Linux driver will eventually configure the watchdog for 1MHz mode
> > regardless so perhaps the AST2400 reset state is a bit of a corner case, but
> > I feel the assertion should be watered down a bit?
> 
> What about this description?
> 
> "The current implementation uses nano-second precision, but
>  is not more precise than micro-second precision.
>  Simplify by using a micro-second based timer.
>  Rename the timer 'timer_us' to have the unit explicit."

So is this a limitation of QEMUTimer? I was establishing that the hardware can 
operate at greater than 1 micro-second precision.

Andrew



Re: [PATCH 7/7] hw/watchdog/wdt_aspeed: Reduce timer precision to micro-second

2020-06-16 Thread Andrew Jeffery



On Tue, 16 Jun 2020, at 17:21, Philippe Mathieu-Daudé wrote:
> The current implementation uses nano-second precision, while
> the watchdog can not be more precise than a micro-second.

What's the basis for this assertion? It's true for the AST2500 and AST2600, but 
the AST2400 can run the watchdog from either a 1MHz clock source or the APB 
clock (which must be at least 16.5MHz on palmetto). The reset state on the
AST2400 configures the watchdog for the APB clock rate.

The Linux driver will eventually configure the watchdog for 1MHz mode
regardless so perhaps the AST2400 reset state is a bit of a corner case, but
I feel the assertion should be watered down a bit?

Andrew



Re: [PATCH] docs/system: Document Aspeed boards

2020-06-02 Thread Andrew Jeffery
> 
> >> + * Hash/Crypto Engine
> >> + * PCI-Express 1 Controller
> >> + * Graphic Display Controller
> >> + * PECI Controller
> >> + * MCTP Controller
> >> + * Mailbox Controller
> >> + * Virtual UART
> > 
> > Uh what is that? :)
> 
> It is the host console. 
> 

To explain a little more, a 16550-compatible set of registers are exposed to 
both the host (via e.g. the LPC bus) and the BMC, but the FIFOs are shared and 
the transmissions are nothing more than register writes/reads from each side. 
There's no RS-232 involved, hence "Virtual" I guess.

Andrew



Re: [PATCH 04/24] aspeed: Don't create unwanted "ftgmac100", "aspeed-mmi" devices

2020-05-18 Thread Andrew Jeffery



On Mon, 18 May 2020, at 21:49, Cédric Le Goater wrote:
> On 5/18/20 7:03 AM, Markus Armbruster wrote:
> > These devices are optional, and controlled by @nb_nics.
> > aspeed_soc_ast2600_init() and aspeed_soc_init() create the maximum
> > supported number.  aspeed_soc_ast2600_realize() and
> > aspeed_soc_realize() realize only the wanted number.  Works, although
> > it can leave unrealized devices hanging around in the QOM composition
> > tree.  Affects machines ast2500-evb, ast2600-evb, palmetto-bmc,
> > romulus-bmc, swift-bmc, tacoma-bmc, and witherspoon-bmc.
> > 
> > Make the init functions create only the wanted ones.  Visible in "info
> > qom-tree"; here's the change for ast2600-evb:
> > 
> >  /machine (ast2600-evb-machine)
> >[...]
> >/soc (ast2600-a1)
> >  [...]
> >  /ftgmac100[0] (ftgmac100)
> >/ftgmac100[0] (qemu:memory-region)
> > -/ftgmac100[1] (ftgmac100)
> > -/ftgmac100[2] (ftgmac100)
> > -/ftgmac100[3] (ftgmac100)
> >  /gpio (aspeed.gpio-ast2600)
> >  [...]
> >  /mii[0] (aspeed-mmi)
> >/aspeed-mmi[0] (qemu:memory-region)
> > -/mii[1] (aspeed-mmi)
> > -/mii[2] (aspeed-mmi)
> > -/mii[3] (aspeed-mmi)
> >  /rtc (aspeed.rtc)
> > 
> > I'm not sure creating @nb_nics devices makes sense.  How many does the
> > physical chip provide?
> 
> The AST2400, AST2500 SoC have 2 macs and the AST2600 has 4. Each machine
> define the one it uses, generally MAC0 but the tacoma board uses MAC3.
> 
> Shouldn't the model reflect the real address space independently from
> the NIC backends defined on the command line ?  

That's my feeling too, though I'm not sure what to make of the unrealised 
devices
in the QOM tree. Does it matter? It hasn't bothered me.

Andrew



Re: [PATCH] aspeed: Support AST2600A1 silicon revision

2020-05-04 Thread Andrew Jeffery



On Mon, 4 May 2020, at 19:07, Joel Stanley wrote:
> There are minimal differences from Qemu's point of view between the A0
> and A1 silicon revisions.
> 
> As the A1 exercises different code paths in u-boot it is desirable to
> emulate that instead.
> 
> Signed-off-by: Joel Stanley 
> ---
>  hw/arm/aspeed.c  |  8 
>  hw/arm/aspeed_ast2600.c  |  6 +++---
>  hw/misc/aspeed_scu.c | 11 +--
>  include/hw/misc/aspeed_scu.h |  1 +
>  4 files changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 99a0f3fcf36e..91301efab32d 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -93,7 +93,7 @@ struct AspeedBoardState {
>  
>  /* Tacoma hardware value */
>  #define TACOMA_BMC_HW_STRAP1  0x
> -#define TACOMA_BMC_HW_STRAP2  0x
> +#define TACOMA_BMC_HW_STRAP2  0x0040
>  
>  /*
>   * The max ram region is for firmwares that scan the address space
> @@ -585,7 +585,7 @@ static void 
> aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
>  AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
>  
>  mc->desc   = "Aspeed AST2600 EVB (Cortex A7)";
> -amc->soc_name  = "ast2600-a0";
> +amc->soc_name  = "ast2600-a1";
>  amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
>  amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
>  amc->fmc_model = "w25q512jv";
> @@ -600,8 +600,8 @@ static void 
> aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
>  MachineClass *mc = MACHINE_CLASS(oc);
>  AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
>  
> -    mc->desc   = "Aspeed AST2600 EVB (Cortex A7)";
> -amc->soc_name  = "ast2600-a0";
> +mc->desc   = "OpenPOWER Tacoma BMC (Cortex A7)";

Lol, whoops.

Reviewed-by: Andrew Jeffery 



Re: [PATCH v1] nrf51: Fix last GPIO CNF address

2020-04-10 Thread Andrew Jeffery



On Fri, 10 Apr 2020, at 21:56, Peter Maydell wrote:
> On Fri, 10 Apr 2020 at 04:42, Andrew Jeffery  wrote:
> > IIRC Phil wanted to enable sub-word accesses to the sample value
> > registers but I didn't want to spread logic dealing with different access
> > widths through the model. We already had a mechanism to describe the
> > model's  supported access sizes (as opposed to the valid access sizes
> > allowed by hardware) in the `impl` member of the MemoryRegionOps, so
> > I was trying to use that, but it didn't work as I needed.
> >
> > The accesses generated at the point of the guest MMIO need to be
> > expanded to the access width supported by the model and then the
> > resulting data trimmed again upon returning the data (in the case of a
> > read) via the MMIO operation.
> >
> > So the intent was less about unaligned accesses than enabling models
> > implementations that only have to handle certain-sized access widths.
> > It happens to help the unaligned access case as well.
> 
> Yeah, we definitely could do with improving things here, it is annoying
> to have to write code for handling some of the oddball cases when you
> have just one register that allows byte accesses or whatever.
> The thing I have in the back of my mind as a concern is that we have
> had several "is this a buffer overrun" questions where the answer has
> been "it can't be, because the core code doesn't allow a call to the
> read/write function for a 4 byte access where the address is not 4-aligned,
> so my_byte_array[addr] is always in-bounds".
> So if we change the core code we need to make sure we don't
> inadvertently remove a restriction that was protecting us from a guest
> escape...

Oh for sure. The patch was very RFC, as mentioned I just sent it to check
whether I was on the right track or off in the weeds, and from there it has
hung around in Cedric's tree without much progress.

Feels like the time is right to sort the problem out properly, which might
mean starting from scratch to make sure we don't miss any of the details.

Andrew



Re: [PATCH v1] nrf51: Fix last GPIO CNF address

2020-04-09 Thread Andrew Jeffery



On Tue, 7 Apr 2020, at 18:20, Peter Maydell wrote:
> On Tue, 7 Apr 2020 at 09:45, Joel Stanley  wrote:
> > On Tue, 7 Apr 2020 at 08:41, Peter Maydell  wrote:
> > > Do you have a link to this patch, please? I had a quick search through
> > > my mailing list articles but couldn't see anything obviously relevant.
> >
> > There is a reference in this thread:
> >
> > https://lore.kernel.org/qemu-devel/dd8fc1f7-56d9-4d9f-96a4-0fdcafdc8...@www.fastmail.com/
> >
> > The patch is here:
> >
> > https://lore.kernel.org/qemu-devel/20170630030058.28943-1-and...@aj.id.au/
> 
> Oh, that's from 2017, no wonder I couldn't find it!

Yeah, I never quite got back to finishing it :(

It's development was driven by development of the ASPEED ADC model,
which I hacked up in the interest of getting the ASPEED SDK booting
under qemu (the SDK kernel had an infinite spin waiting for the ADC-ready
bit).

IIRC Phil wanted to enable sub-word accesses to the sample value
registers but I didn't want to spread logic dealing with different access
widths through the model. We already had a mechanism to describe the
model's  supported access sizes (as opposed to the valid access sizes
allowed by hardware) in the `impl` member of the MemoryRegionOps, so
I was trying to use that, but it didn't work as I needed.

The accesses generated at the point of the guest MMIO need to be
expanded to the access width supported by the model and then the
resulting data trimmed again upon returning the data (in the case of a
read) via the MMIO operation.

So the intent was less about unaligned accesses than enabling models
implementations that only have to handle certain-sized access widths.
It happens to help the unaligned access case as well.

> 
> Does somebody who's already reviewed the patch want to summarize
> what the effects on devices are -- i.e. what calls the device's read/write
> methods used to get if the guest did an unaligned access, including an
> unaligned access half off-the-end of the memory region, and what
> calls the read/write methods get after the patch ? The patch's commit
> message doesn't really describe what it's doing...

Honestly any of that information has well left my memory at this point, I'd
have to analyse the patch to recover it.

I was hoping that my turn-around time would be shorter than 3 years but
there hasn't been a shortage of fires to put out in the mean time.

Andrew



Re: [PATCH for-5.0] hw/gpio/aspeed_gpio.c: Don't directly include assert.h

2020-04-05 Thread Andrew Jeffery



On Fri, 3 Apr 2020, at 23:17, Peter Maydell wrote:
> Remove a direct include of assert.h -- this is already
> provided by qemu/osdep.h, and it breaks our rule that the
> first include must always be osdep.h.
> 
> In particular we must get the assert() macro via osdep.h
> to avoid compile failures on mingw (see the comment in
> osdep.h where we redefine assert() for that platform).
> 
> Signed-off-by: Peter Maydell 

Acked-by: Andrew Jeffery 



Re: [PATCH v1] usb: Add read support for HCIVERSION register to XHCI

2020-04-02 Thread Andrew Jeffery



On Wed, 1 Apr 2020, at 21:53, Cédric Le Goater wrote:
> Hello,
> 
> On 3/31/20 1:02 PM, Philippe Mathieu-Daudé wrote:
> > On 3/31/20 11:57 AM, Cameron Esfahani wrote:
> >> Philippe -
> >>  From what I've seen, access size has nothing to do with alignment.
> > 
> > Yes, I was wondering if you were using unaligned accesses.
> > 
> > I *think* the correct fix is in the "memory: Support unaligned accesses on 
> > aligned-only models" patch from Andrew Jeffery:
> > https://www.mail-archive.com/qemu-devel@nongnu.org/msg461247.html
> 
> Here is an updated version I have been keeping since : 
> 
>   
> https://github.com/legoater/qemu/commit/d57ac950c4be47a2bafd6c6a96dec2922c2ecd65
> 
> which breaks qtest :
> 
>   microbit-test.c:307:test_nrf51_gpio: assertion failed (actual == 
> 0x01): (0 == 1)
> 
> I haven't had time to look at this closely but it would be nice to get this 
> patch merged.

Second this! I never had the chance to circle back and fix it up.

Andrew



Re: [PATCH 2/2] aspeed/smc: Fix User mode select/unselect scheme

2020-02-19 Thread Andrew Jeffery



On Thu, 6 Feb 2020, at 21:56, Cédric Le Goater wrote:
> The Aspeed SMC Controller can operate in different modes : Read, Fast
> Read, Write and User modes. When the User mode is configured, it
> selects automatically the SPI slave device until the CE_STOP_ACTIVE
> bit is set to 1. When any other modes are configured the device is
> unselected. The HW logic handles the chip select automatically when
> the flash is accessed through its AHB window.
> 
> When configuring the CEx Control Register, the User mode logic to
> select and unselect the slave is incorrect and data corruption can be
> seen on machines using two chips, witherspoon and romulus.
> 
> Rework the handler setting the CEx Control Register to fix this issue.
> 
> Fixes: 7c1c69bca43c ("ast2400: add SMC controllers (FMC and SPI)")
> Signed-off-by: Cédric Le Goater 

Champion!

Reviewed-by: Andrew Jeffery 



Re: [PATCH 1/2] aspeed/smc: Add some tracing

2020-02-19 Thread Andrew Jeffery



On Thu, 6 Feb 2020, at 21:56, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Andrew Jeffery 



Re: [PATCH 2/2] aspeed/scu: Implement chip ID register

2020-01-20 Thread Andrew Jeffery



On Tue, 21 Jan 2020, at 12:03, Joel Stanley wrote:
> This returns a fixed but non-zero value for the chip id.
> 
> Signed-off-by: Joel Stanley 

Reviewed-by: Andrew Jeffery 
> ---
>  hw/misc/aspeed_scu.c | 13 +
>  1 file changed, 13 insertions(+)
> 
> diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> index 7108cad8c6a7..19d1780a40da 100644
> --- a/hw/misc/aspeed_scu.c
> +++ b/hw/misc/aspeed_scu.c
> @@ -77,6 +77,8 @@
>  #define CPU2_BASE_SEG4   TO_REG(0x110)
>  #define CPU2_BASE_SEG5   TO_REG(0x114)
>  #define CPU2_CACHE_CTRL  TO_REG(0x118)
> +#define CHIP_ID0 TO_REG(0x150)
> +#define CHIP_ID1 TO_REG(0x154)
>  #define UART_HPLL_CLKTO_REG(0x160)
>  #define PCIE_CTRLTO_REG(0x180)
>  #define BMC_MMIO_CTRLTO_REG(0x184)
> @@ -115,6 +117,8 @@
>  #define AST2600_HW_STRAP2_PROTTO_REG(0x518)
>  #define AST2600_RNG_CTRL  TO_REG(0x524)
>  #define AST2600_RNG_DATA  TO_REG(0x540)
> +#define AST2600_CHIP_ID0  TO_REG(0x5B0)
> +#define AST2600_CHIP_ID1  TO_REG(0x5B4)
>  
>  #define AST2600_CLK TO_REG(0x40)
>  
> @@ -182,6 +186,8 @@ static const uint32_t 
> ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
>   [CPU2_BASE_SEG1]  = 0x8000U,
>   [CPU2_BASE_SEG4]  = 0x1E60U,
>   [CPU2_BASE_SEG5]  = 0xC000U,
> + [CHIP_ID0]= 0x1234ABCDU,
> + [CHIP_ID1]= 0xU,
>   [UART_HPLL_CLK]   = 0x1903U,
>   [PCIE_CTRL]   = 0x007BU,
>   [BMC_DEV_ID]  = 0x2402U
> @@ -307,6 +313,8 @@ static void aspeed_ast2500_scu_write(void *opaque, 
> hwaddr offset,
>  case RNG_DATA:
>  case FREE_CNTR4:
>  case FREE_CNTR4_EXT:
> +case CHIP_ID0:
> +case CHIP_ID1:
>  qemu_log_mask(LOG_GUEST_ERROR,
>"%s: Write to read-only offset 0x%" HWADDR_PRIx 
> "\n",
>__func__, offset);
> @@ -620,6 +628,8 @@ static void aspeed_ast2600_scu_write(void *opaque, 
> hwaddr offset,
>  case AST2600_RNG_DATA:
>  case AST2600_SILICON_REV:
>  case AST2600_SILICON_REV2:
> +case AST2600_CHIP_ID0:
> +case AST2600_CHIP_ID1:
>  /* Add read only registers here */
>  qemu_log_mask(LOG_GUEST_ERROR,
>"%s: Write to read-only offset 0x%" HWADDR_PRIx 
> "\n",
> @@ -648,6 +658,9 @@ static const uint32_t 
> ast2600_a0_resets[ASPEED_AST2600_SCU_NR_REGS] = {
>  [AST2600_CLK_STOP_CTRL2]= 0xFFF0FFF0,
>  [AST2600_SDRAM_HANDSHAKE]   = 0x0040,  /* SoC completed DRAM 
> init */
>  [AST2600_HPLL_PARAM]= 0x1000405F,
> +[AST2600_CHIP_ID0]  = 0x1234ABCD,
> +[AST2600_CHIP_ID1]  = 0x,

Probably should add the explicit trailing 'U' to the constants at some point.

Reviewed-by: Andrew Jeffery 



Re: [PATCH 1/2] aspeed/scu: Create separate write callbacks

2020-01-20 Thread Andrew Jeffery



On Tue, 21 Jan 2020, at 12:03, Joel Stanley wrote:
> This splits the common write callback into separate ast2400 and ast2500
> implementations. This makes it clearer when implementing differing
> behaviour.
> 
> Signed-off-by: Joel Stanley 

Reviewed-by: Andrew Jeffery 



Re: [PATCH 2/5] hw/arm: ast2600: Wire up the eMMC controller

2020-01-12 Thread Andrew Jeffery



On Fri, 10 Jan 2020, at 22:26, Cédric Le Goater wrote:
> >> +
> >> +    sysbus_init_child_obj(obj, "emmc", OBJECT(>emmc), sizeof(s->emmc),
> >> +  TYPE_ASPEED_SDHCI);
> >> +
> >> +    object_property_set_int(OBJECT(>emmc), 1, "num-slots", 
> >> _abort);
> >> +
> >> +    sysbus_init_child_obj(obj, "emmc[*]", OBJECT(>emmc.slots[0]),
> > 
> > Single block, so use "emmc" instead.
> 
> Andrew, how should we call the objects in the slots ? "sdhci" ? 

I think that's the right way to go, but maybe we need to rethink the naming at 
the
controller level.

Andrew



Re: [PATCH v3 0/4] Expose GT CNTFRQ as a CPU property to support AST2600

2019-12-17 Thread Andrew Jeffery



On Wed, 18 Dec 2019, at 01:55, Peter Maydell wrote:
> On Fri, 13 Dec 2019 at 05:48, Andrew Jeffery  wrote:
> >
> > Hello,
> >
> > This is a v3 of the belated follow-up from a few of my earlier attempts to 
> > fix
> > up the ARM generic timer for correct behaviour on the ASPEED AST2600 SoC. 
> > The
> > AST2600 clocks the generic timer at the rate of HPLL, which is configured to
> > 1125MHz.  This is significantly quicker than the currently hard-coded 
> > generic
> > timer rate of 62.5MHz and so we see "sticky" behaviour in the guest.
> >
> > v2 can be found here:
> >
> > https://patchwork.ozlabs.org/cover/1203474/
> >
> > Changes since v2:
> >
> > * Address some minor review comments from Philippe and add tags
> >
> > Changes since v1:
> >
> > * Fix a user mode build failure from partial renaming of 
> > gt_cntfrq_period_ns()
> > * Add tags from Cedric and Richard
> >
> > Please review.
> >
> > Andrew
> >
> > Andrew Jeffery (4):
> >   target/arm: Remove redundant scaling of nexttick
> >   target/arm: Abstract the generic timer frequency
> >   target/arm: Prepare generic timer for per-platform CNTFRQ
> >   ast2600: Configure CNTFRQ at 1125MHz
> 
> 
> 
> 
> Applied to target-arm.next, thanks.

Thanks for your feedback throughout.

Andrew



Re: [PATCH v2 0/2] hw/arm: ast2600: Wire up eMMC controller

2019-12-12 Thread Andrew Jeffery



On Fri, 13 Dec 2019, at 18:03, Cédric Le Goater wrote:
> On 13/12/2019 05:28, Andrew Jeffery wrote:
> > Hello,
> > 
> > The AST2600 has an additional SDHCI intended for use as an eMMC boot source.
> > These two patches rework the existing ASPEED SDHCI model to accommodate the
> > single-slot nature of the eMMC controller and wire it into the AST2600 SoC.
> > 
> > v2 contains some minor refactorings in response to issues pointed out by
> > Cedric.
>  
> 
> I think these patches are based on mainline. I fixed them locally on 
> my aspeed 5.0 branch and I plan to send them along with other aspeed 
> changes in the 5.0 timeframe.  

Yeah, they're based on Peter's tree. I'll base future patches on yours.

Andrew



[PATCH v3 4/4] ast2600: Configure CNTFRQ at 1125MHz

2019-12-12 Thread Andrew Jeffery
This matches the configuration set by u-boot on the AST2600.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Richard Henderson 
Reviewed-by: Cédric Le Goater 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/arm/aspeed_ast2600.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 931887ac681f..5aecc3b3caec 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -259,6 +259,9 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 object_property_set_int(OBJECT(>cpu[i]), aspeed_calc_affinity(i),
 "mp-affinity", _abort);
 
+object_property_set_int(OBJECT(>cpu[i]), 112500, "cntfrq",
+_abort);
+
 /*
  * TODO: the secondary CPUs are started and a boot helper
  * is needed when using -kernel
-- 
git-series 0.9.1



  1   2   3   >