Re: [Qemu-devel] [RFC PATCH 1/1] memory: Support unaligned accesses on aligned-only models

2017-07-14 Thread Andrew Jeffery
Hi Paolo,

Thanks for taking a look!

On Thu, 2017-07-13 at 14:05 +0200, Paolo Bonzini wrote:
> On 30/06/2017 05:00, Andrew Jeffery wrote:
> > This RFC patch stems from a discussion on a patch for an ADC model[1] where 
> > it
> > was pointed out that I should be able to use the .impl member of
> > MemoryRegionOps to constrain how my read() and write() callbacks where 
> > invoked.
> > 
> > I tried Phil's suggested approach and found I got reads of size 4, but with 
> > an
> > address that was not 4-byte aligned.
> > 
> > Looking at the source for access_with_adjusted_size() lead to the comment
> > 
> >  /* FIXME: support unaligned access? */
> > 
> > which at least suggests that the implementation isn't complete.
> > 
> > So, this patch is a quick and incomplete attempt at resolving the issue to 
> > see
> > whether I'm on the right track or way off in the weeds.
> > 
> > I've lightly tested it with the ADC model mentioned above, and it appears 
> > to do
> > the right thing (I changed the values generated by the ADC to distinguish
> > between the lower and upper 16 bits).
> 
> I think the idea is okay.
> 
> > +access_addr[0] = align_down(addr, access_size);
> > +access_addr[1] = align_up(addr + size, access_size);
> > +
> > +for (cur = access_addr[0]; cur < access_addr[1]; cur += 
> > access_size) {
> > +uint64_t mask_bounds[2];
> > +mask_bounds[0] = MAX(addr, cur) - cur;
> > +mask_bounds[1] =
> > +MIN(addr + size, align_up(cur + 1, access_size)) - cur;
> > +
> > +access_mask = (-1ULL << mask_bounds[0] * 8) &
> > +(-1ULL >> (64 - mask_bounds[1] * 8));
> 
> Please use MAKE_64BIT_MASK.

Okay.

> 
> > +r |= access(mr, cur, _value, access_size,
> > +  (MAX(addr, cur) - addr), access_mask, attrs);
> > +
> > +/* XXX: Can't do this hack for writes */
> > +access_value >>= mask_bounds[0] * 8;
> > +}
> 
> Can you subtract access_addr[0] from mask_bounds[0] and mask_bounds[1]
> (instead of cur) to remove the need for this right shift?

I haven't looked at the patch since I sent it. Given you think the idea
 of the patch is okay I'll get back to working on it and think about
this.

Cheers,

Andrew

> 
> Thanks,
> 
> Paolo

signature.asc
Description: This is a digitally signed message part


[Qemu-devel] [RFC PATCH 1/1] memory: Support unaligned accesses on aligned-only models

2017-06-29 Thread Andrew Jeffery
Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Hello,

This RFC patch stems from a discussion on a patch for an ADC model[1] where it
was pointed out that I should be able to use the .impl member of
MemoryRegionOps to constrain how my read() and write() callbacks where invoked.

I tried Phil's suggested approach and found I got reads of size 4, but with an
address that was not 4-byte aligned.

Looking at the source for access_with_adjusted_size() lead to the comment

 /* FIXME: support unaligned access? */

which at least suggests that the implementation isn't complete.

So, this patch is a quick and incomplete attempt at resolving the issue to see
whether I'm on the right track or way off in the weeds.

I've lightly tested it with the ADC model mentioned above, and it appears to do
the right thing (I changed the values generated by the ADC to distinguish
between the lower and upper 16 bits).

Things the patch is not:

1. Capable of handling unaligned writes
2. Tested on big-endian models

If the general idea of the patch is reasonable I'll look to resolve the above
to points.

Cheers,

Andrew

[1] http://lists.nongnu.org/archive/html/qemu-arm/2017-05/msg00400.html
 memory.c | 144 +++
 1 file changed, 137 insertions(+), 7 deletions(-)

diff --git a/memory.c b/memory.c
index 0ddc4cc28deb..b9fae8d382bc 100644
--- a/memory.c
+++ b/memory.c
@@ -432,6 +432,7 @@ static MemTxResult  
memory_region_read_accessor(MemoryRegion *mr,
 {
 uint64_t tmp;
 
+
 tmp = mr->ops->read(mr->opaque, addr, size);
 if (mr->subpage) {
 trace_memory_region_subpage_read(get_cpu_index(), mr, addr, tmp, size);
@@ -552,7 +553,7 @@ static MemTxResult 
memory_region_write_with_attrs_accessor(MemoryRegion *mr,
 return mr->ops->write_with_attrs(mr->opaque, addr, tmp, size, attrs);
 }
 
-static MemTxResult access_with_adjusted_size(hwaddr addr,
+static MemTxResult access_with_adjusted_size_aligned(hwaddr addr,
   uint64_t *value,
   unsigned size,
   unsigned access_size_min,
@@ -567,10 +568,11 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
   MemoryRegion *mr,
   MemTxAttrs attrs)
 {
+
+MemTxResult r = MEMTX_OK;
 uint64_t access_mask;
 unsigned access_size;
 unsigned i;
-MemTxResult r = MEMTX_OK;
 
 if (!access_size_min) {
 access_size_min = 1;
@@ -579,7 +581,6 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
 access_size_max = 4;
 }
 
-/* FIXME: support unaligned access? */
 access_size = MAX(MIN(size, access_size_max), access_size_min);
 access_mask = -1ULL >> (64 - access_size * 8);
 if (memory_region_big_endian(mr)) {
@@ -596,6 +597,133 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
 return r;
 }
 
+/* Assume power-of-two size */
+#define align_down(addr, size) ((addr) & ~((size) - 1))
+#define align_up(addr, size) \
+({ typeof(size) __size = size; align_down((addr) + (__size) - 1, 
(__size)); })
+
+static MemTxResult access_with_adjusted_size_unaligned(hwaddr addr,
+  uint64_t *value,
+  unsigned size,
+  unsigned access_size_min,
+  unsigned access_size_max,
+  bool unaligned,
+  MemTxResult (*access)(MemoryRegion *mr,
+hwaddr addr,
+uint64_t *value,
+unsigned size,
+unsigned shift,
+uint64_t mask,
+MemTxAttrs attrs),
+  MemoryRegion *mr,
+  MemTxAttrs attrs)
+{
+uint64_t access_value = 0;
+MemTxResult r = MEMTX_OK;
+hwaddr access_addr[2];
+uint64_t access_mask;
+unsigned access_size;
+
+if (unlikely(!access_size_min)) {
+access_size_min = 1;
+}
+if (unlikely(!access_size_max)) {
+access_size_max = 4;
+}
+
+access_size = MAX(MIN(size, access_size_max), access_size_min);
+access_addr[0] = align_down(addr, access_size);
+access_addr[1] = align_up(addr + size, access_size);
+
+if (memory_region_big_endian(mr)) {
+hwaddr cur;
+
+/* XXX: Big-endian path is untested...  */
+
+for (cur = access_addr[0]; cur < access_addr[1]; cur += access_size) {
+uint64_t mask_bounds[2];
+
+ 

Re: [Qemu-devel] [PATCH] timer/aspeed: fix timer enablement when a reload is not set

2017-06-12 Thread Andrew Jeffery
On Fri, 2017-06-09 at 07:40 +0200, Cédric Le Goater wrote:
> On 06/09/2017 04:26 AM, Andrew Jeffery wrote:
> > On Tue, 2017-06-06 at 10:55 +0200, Cédric Le Goater wrote:
> > > When a timer is enabled before a reload value is set, the controller
> > > waits for a reload value to be set before starting decrementing. This
> > > fix tries to cover that case by changing the timer expiry only when
> > > a reload value is valid.
> > > 
> > > > Signed-off-by: Cédric Le Goater <c...@kaod.org>
> > > 
> > > ---
> > >  hw/timer/aspeed_timer.c | 37 +
> > >  1 file changed, 29 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
> > > index 9b70ee09b07f..50acbf530a3a 100644
> > > --- a/hw/timer/aspeed_timer.c
> > > +++ b/hw/timer/aspeed_timer.c
> > > @@ -130,15 +130,26 @@ static uint64_t calculate_next(struct AspeedTimer 
> > > *t)
> > >  next = seq[1];
> > >  } else if (now < seq[2]) {
> > >  next = seq[2];
> > > -} else {
> > > +} 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;
> > >  }
> > >  }
> > >  
> > >  return next;
> > >  }
> > >  
> > > +static void aspeed_timer_mod(AspeedTimer *t)
> > > +{
> > > +uint64_t next = calculate_next(t);
> > > +if (next) {
> > > +timer_mod(>timer, next);
> > > +}
> > > +}
> > > +
> > >  static void aspeed_timer_expire(void *opaque)
> > >  {
> > >  AspeedTimer *t = opaque;
> > > @@ -164,7 +175,7 @@ static void aspeed_timer_expire(void *opaque)
> > >  qemu_set_irq(t->irq, t->level);
> > >  }
> > >  
> > > -timer_mod(>timer, calculate_next(t));
> > > +aspeed_timer_mod(t);
> > >  }
> > >  
> > >  static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
> > > @@ -227,10 +238,23 @@ static void 
> > > aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
> > > uint32_t value)
> > >  {
> > >  AspeedTimer *t;
> > > +uint32_t old_reload;
> > >  
> > >  trace_aspeed_timer_set_value(timer, reg, value);
> > >  t = >timers[timer];
> > >  switch (reg) {
> > > +case TIMER_REG_RELOAD:
> > > +old_reload = t->reload;
> > > +t->reload = value;
> > > +
> > > +/* If the reload value was not previously set, or zero, and
> > > + * the current value is valid, try to start the timer if it is
> > > + * enabled.
> > > + */
> > > +if (old_reload || !t->reload) {
> > > +break;
> > > +}
> > 
> > Maybe I need more caffeine, but I initially struggled to reconcile the
> > condition with the comment, as the condition checks the inverse in
> > order to break while the comment discusses the non-breaking case. 
> 
> I agree. The reload "value" is used in a hidden way to the activate the 
> timer.
> 
> > However, after trying for several minutes, I'm not sure there's an easy
> > way to improve it.
> 
> I tried a few things. May be, we could move the following code in 
> its own routine and call it twice ? 

I don't think it's necessary. The comment serves as enough warning - it
should at least make people think before modifying the code.

Cheers,

Andrew

>  
> > > +
> > >  case TIMER_REG_STATUS:
> > >  if (timer_enabled(t)) {
> > >  uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > > @@ -238,17 +262,14 @@ static void 
> > > aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
> > >  uint32_t rate = calculate_rate(t);
> > >  
> > >  t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
> > > -timer_mod(>timer, calculate_next(t));
> > > +        aspeed_timer_mod(t);
> > >  }
> > >  break;
> > > -case TIMER_REG_RELOAD:
> > > -t->reload = value;
> > > -break;
> > >  case TIMER_REG_MATCH_FIRST:
> > >  case TIMER_REG_MATCH_SECOND:
> > >  t->match[reg - 2] = value;
> > >  if (timer_enabled(t)) {
> > > -timer_mod(>timer, calculate_next(t));
> > > +aspeed_timer_mod(t);
> > >  }
> > >  break;
> > >  default:
> > > @@ -268,7 +289,7 @@ static void aspeed_timer_ctrl_enable(AspeedTimer *t, 
> > > bool enable)
> > >  trace_aspeed_timer_ctrl_enable(t->id, enable);
> > >  if (enable) {
> > >  t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > > -timer_mod(>timer, calculate_next(t));
> > > +aspeed_timer_mod(t);
> > >  } else {
> > >  timer_del(>timer);
> > >  }
> > 
> > Reviewed-by: Andrew Jeffery <and...@aj.id.au>
> 
> Thanks,
> 
> C.

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH] timer/aspeed: fix timer enablement when a reload is not set

2017-06-08 Thread Andrew Jeffery
On Tue, 2017-06-06 at 10:55 +0200, Cédric Le Goater wrote:
> When a timer is enabled before a reload value is set, the controller
> waits for a reload value to be set before starting decrementing. This
> fix tries to cover that case by changing the timer expiry only when
> a reload value is valid.
> 
> > Signed-off-by: Cédric Le Goater <c...@kaod.org>
> ---
>  hw/timer/aspeed_timer.c | 37 +
>  1 file changed, 29 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
> index 9b70ee09b07f..50acbf530a3a 100644
> --- a/hw/timer/aspeed_timer.c
> +++ b/hw/timer/aspeed_timer.c
> @@ -130,15 +130,26 @@ static uint64_t calculate_next(struct AspeedTimer *t)
>  next = seq[1];
>  } else if (now < seq[2]) {
>  next = seq[2];
> -} else {
> +} 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;
>  }
>  }
>  
>  return next;
>  }
>  
> +static void aspeed_timer_mod(AspeedTimer *t)
> +{
> +uint64_t next = calculate_next(t);
> +if (next) {
> +timer_mod(>timer, next);
> +}
> +}
> +
>  static void aspeed_timer_expire(void *opaque)
>  {
>  AspeedTimer *t = opaque;
> @@ -164,7 +175,7 @@ static void aspeed_timer_expire(void *opaque)
>  qemu_set_irq(t->irq, t->level);
>  }
>  
> -timer_mod(>timer, calculate_next(t));
> +aspeed_timer_mod(t);
>  }
>  
>  static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
> @@ -227,10 +238,23 @@ static void aspeed_timer_set_value(AspeedTimerCtrlState 
> *s, int timer, int reg,
> uint32_t value)
>  {
>  AspeedTimer *t;
> +uint32_t old_reload;
>  
>  trace_aspeed_timer_set_value(timer, reg, value);
>  t = >timers[timer];
>  switch (reg) {
> +case TIMER_REG_RELOAD:
> +old_reload = t->reload;
> +t->reload = value;
> +
> +/* If the reload value was not previously set, or zero, and
> + * the current value is valid, try to start the timer if it is
> + * enabled.
> + */
> +if (old_reload || !t->reload) {
> +break;
> +}

Maybe I need more caffeine, but I initially struggled to reconcile the
condition with the comment, as the condition checks the inverse in
order to break while the comment discusses the non-breaking case. 

However, after trying for several minutes, I'm not sure there's an easy
way to improve it.

> +
>  case TIMER_REG_STATUS:
>  if (timer_enabled(t)) {
>  uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> @@ -238,17 +262,14 @@ static void aspeed_timer_set_value(AspeedTimerCtrlState 
> *s, int timer, int reg,
>  uint32_t rate = calculate_rate(t);
>  
>  t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
> -timer_mod(>timer, calculate_next(t));
> +aspeed_timer_mod(t);
>  }
>  break;
> -case TIMER_REG_RELOAD:
> -t->reload = value;
> -break;
>  case TIMER_REG_MATCH_FIRST:
>  case TIMER_REG_MATCH_SECOND:
>  t->match[reg - 2] = value;
>  if (timer_enabled(t)) {
> -timer_mod(>timer, calculate_next(t));
> +aspeed_timer_mod(t);
>  }
>  break;
>  default:
> @@ -268,7 +289,7 @@ static void aspeed_timer_ctrl_enable(AspeedTimer *t, bool 
> enable)
>  trace_aspeed_timer_ctrl_enable(t->id, enable);
>  if (enable) {
>  t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> -timer_mod(>timer, calculate_next(t));
> +aspeed_timer_mod(t);
>  } else {
>  timer_del(>timer);
>  }

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [Qemu-arm] [PATCH 1/2] hw/adc: Add basic Aspeed ADC model

2017-05-23 Thread Andrew Jeffery
On Wed, 2017-05-24 at 02:15 -0300, Philippe Mathieu-Daudé wrote:
> Hi Andrew,
> 
> On 05/22/2017 02:14 AM, Andrew Jeffery wrote:
> > On Mon, 2017-05-22 at 03:15 +, Ryan Chen wrote:
> > > In ASPEED SoC chip, all register access have following rule.
> > > Most of controller write access is only support 32bit access.
> > > Read is support 8bits/16bits/32bits.
> 
> This makes sens thinking about how a DMA controller can take advantage 
> of the ADC.
> 
> > 
> > Thanks for clearing that up Ryan.
> > 
> > Phil: I'll rework the model so the reads are 16-bits.
> 
> This shouldn't be necessary, QEMU is supposed to supports different 
> access size for different implemented size, so you can declare your 
> implementation as 32-bit and valid accesses from 8 to 32:
> 
>   static const MemoryRegionOps aspeed_adc_ops = {
>   .read = aspeed_adc_read,
>   .write = aspeed_adc_write,
>   .endianness = DEVICE_LITTLE_ENDIAN,
>   .valid.min_access_size = 1,
>   .valid.max_access_size = 4,
>   .valid.unaligned = false,
> +.impl.min_access_size = 4,
> +.impl.max_access_size = 4,
>   };
> 
> This way an I/O access from the CPU or a DMA could use 8/16-bit while 
> you keep a 32-bit implementation. The adjustment is done by 
> access_with_adjusted_size() from memory.c.
> 
> Afaik there is, however, no distinction between read/write different 
> access size in current QEMU MemoryRegionOps model.

Yep, I realised all of the above when I went to implement it. Thanks
for pointing it out though!

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [Qemu-arm] [PATCH 1/2] hw/adc: Add basic Aspeed ADC model

2017-05-21 Thread Andrew Jeffery
On Mon, 2017-05-22 at 03:15 +, Ryan Chen wrote:
> In ASPEED SoC chip, all register access have following rule. 
> Most of controller write access is only support 32bit access. 
> Read is support 8bits/16bits/32bits. 

Thanks for clearing that up Ryan.

Phil: I'll rework the model so the reads are 16-bits.

Thanks,

Andrew

> 
> 
> 
> Best Regards,
> Ryan
> 
> 信驊科技股份有限公司
> ASPEED Technology Inc.
> 2F,No.15,Industry East Road 4.,Hsinchu Science Park, Hsinchu City 30077, 
> Taiwan
> Tel: 886-3-578-9568  #857
> Fax: 886-3-578-9586
> * Email Confidentiality Notice 
> DISCLAIMER:
> This message (and any attachments) may contain legally privileged and/or 
> other confidential information. If you have received it in error, please 
> notify the sender by reply e-mail and immediately delete the e-mail and any 
> attachments without copying or disclosing the contents. Thank you.
> 
> -Original Message-
> > From: Andrew Jeffery [mailto:and...@aj.id.au] 
> Sent: Monday, May 22, 2017 8:24 AM
> > To: Philippe Mathieu-Daudé <f4...@amsat.org>; qemu-...@nongnu.org
> > > > Cc: Peter Maydell <peter.mayd...@linaro.org>; Ryan Chen 
> > > > <ryan_c...@aspeedtech.com>; Alistair Francis <alist...@alistair23.me>; 
> > > > qemu-devel@nongnu.org; Cédric Le Goater <c...@kaod.org>; Joel Stanley 
> > > > <j...@jms.id.au>
> Subject: Re: [Qemu-arm] [PATCH 1/2] hw/adc: Add basic Aspeed ADC model
> 
> Hi Phil,
> 
> On Sat, 2017-05-20 at 00:21 -0300, Philippe Mathieu-Daudé wrote:
> > Hi Andrew,
> > 
> > On 05/19/2017 09:26 PM, Andrew Jeffery wrote:
> > > This model implements enough behaviour to do basic functionality 
> > > tests such as device initialisation and read out of dummy sample 
> > > values. The sample value generation strategy is similar to the STM 
> > > ADC already in the tree.
> > > 
> > > > > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > > 
> > > ---
> > >  hw/adc/Makefile.objs|   1 +
> > >  hw/adc/aspeed_adc.c | 246 
> > > 
> > >  include/hw/adc/aspeed_adc.h |  33 ++
> > >  3 files changed, 280 insertions(+)
> > >  create mode 100644 hw/adc/aspeed_adc.c
> > >  create mode 100644 include/hw/adc/aspeed_adc.h
> > > 
> > > diff --git a/hw/adc/Makefile.objs b/hw/adc/Makefile.objs index 
> > > 3f6dfdedaec7..2bf9362ba3c4 100644
> > > --- a/hw/adc/Makefile.objs
> > > +++ b/hw/adc/Makefile.objs
> > > @@ -1 +1,2 @@
> > >  obj-$(CONFIG_STM32F2XX_ADC) += stm32f2xx_adc.o
> > > +obj-$(CONFIG_ASPEED_SOC) += aspeed_adc.o
> > > diff --git a/hw/adc/aspeed_adc.c b/hw/adc/aspeed_adc.c new file mode 
> > > 100644 index ..d08f1684f7bc
> > > --- /dev/null
> > > +++ b/hw/adc/aspeed_adc.c
> > > @@ -0,0 +1,246 @@
> > > +/*
> > > + * Aspeed ADC
> > > + *
> > > > > + * Andrew Jeffery <and...@aj.id.au>
> > > 
> > > + *
> > > + * Copyright 2017 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 "hw/adc/aspeed_adc.h"
> > > +#include "qapi/error.h"
> > > +#include "qemu/log.h"
> > > +
> > > +#define ASPEED_ADC_ENGINE_CTRL  0x00 #define  
> > > +ASPEED_ADC_ENGINE_CH_EN_MASK   0x #define   
> > > +ASPEED_ADC_ENGINE_CH_EN(x)((BIT(x)) << 16) #define  
> > > +ASPEED_ADC_ENGINE_INIT BIT(8) #define  
> > > +ASPEED_ADC_ENGINE_AUTO_COMPBIT(5) #define  
> > > +ASPEED_ADC_ENGINE_COMP BIT(4) #define  
> > > +ASPEED_ADC_ENGINE_MODE_MASK0x000e #define   
> > > +ASPEED_ADC_ENGINE_MODE_OFF(0b000 << 1) #define   
> > > +ASPEED_ADC_ENGINE_MODE_STANDBY(0b001 << 1) #define   
> > > +ASPEED_ADC_ENGINE_MODE_NORMAL (0b111 << 1) #define  
> > > +ASPEED_ADC_ENGINE_EN   BIT(0)
> > > +
> > > +#define ASPEED_ADC_L_MASK   ((1 << 10) - 1) #define 
> > > +ASPEED_ADC_L(x) ((x) & ASPEED_ADC_L_MASK) #define 
> > > +ASPEED_ADC_H(x) (((x) >> 16) & ASPEED_ADC_L_MASK) #define 
> > > +ASPEED_ADC_LH_MASK  

Re: [Qemu-devel] [Qemu-arm] [PATCH 1/2] hw/adc: Add basic Aspeed ADC model

2017-05-21 Thread Andrew Jeffery
Hi Phil,

On Sat, 2017-05-20 at 00:21 -0300, Philippe Mathieu-Daudé wrote:
> Hi Andrew,
> 
> On 05/19/2017 09:26 PM, Andrew Jeffery wrote:
> > This model implements enough behaviour to do basic functionality tests
> > such as device initialisation and read out of dummy sample values. The
> > sample value generation strategy is similar to the STM ADC already in
> > the tree.
> > 
> > > > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > ---
> >  hw/adc/Makefile.objs|   1 +
> >  hw/adc/aspeed_adc.c | 246 
> > 
> >  include/hw/adc/aspeed_adc.h |  33 ++
> >  3 files changed, 280 insertions(+)
> >  create mode 100644 hw/adc/aspeed_adc.c
> >  create mode 100644 include/hw/adc/aspeed_adc.h
> > 
> > diff --git a/hw/adc/Makefile.objs b/hw/adc/Makefile.objs
> > index 3f6dfdedaec7..2bf9362ba3c4 100644
> > --- a/hw/adc/Makefile.objs
> > +++ b/hw/adc/Makefile.objs
> > @@ -1 +1,2 @@
> >  obj-$(CONFIG_STM32F2XX_ADC) += stm32f2xx_adc.o
> > +obj-$(CONFIG_ASPEED_SOC) += aspeed_adc.o
> > diff --git a/hw/adc/aspeed_adc.c b/hw/adc/aspeed_adc.c
> > new file mode 100644
> > index ..d08f1684f7bc
> > --- /dev/null
> > +++ b/hw/adc/aspeed_adc.c
> > @@ -0,0 +1,246 @@
> > +/*
> > + * Aspeed ADC
> > + *
> > > > + * Andrew Jeffery <and...@aj.id.au>
> > + *
> > + * Copyright 2017 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 "hw/adc/aspeed_adc.h"
> > +#include "qapi/error.h"
> > +#include "qemu/log.h"
> > +
> > +#define ASPEED_ADC_ENGINE_CTRL  0x00
> > +#define  ASPEED_ADC_ENGINE_CH_EN_MASK   0x
> > +#define   ASPEED_ADC_ENGINE_CH_EN(x)((BIT(x)) << 16)
> > +#define  ASPEED_ADC_ENGINE_INIT BIT(8)
> > +#define  ASPEED_ADC_ENGINE_AUTO_COMPBIT(5)
> > +#define  ASPEED_ADC_ENGINE_COMP BIT(4)
> > +#define  ASPEED_ADC_ENGINE_MODE_MASK0x000e
> > +#define   ASPEED_ADC_ENGINE_MODE_OFF(0b000 << 1)
> > +#define   ASPEED_ADC_ENGINE_MODE_STANDBY(0b001 << 1)
> > +#define   ASPEED_ADC_ENGINE_MODE_NORMAL (0b111 << 1)
> > +#define  ASPEED_ADC_ENGINE_EN   BIT(0)
> > +
> > +#define ASPEED_ADC_L_MASK   ((1 << 10) - 1)
> > +#define ASPEED_ADC_L(x) ((x) & ASPEED_ADC_L_MASK)
> > +#define ASPEED_ADC_H(x) (((x) >> 16) & ASPEED_ADC_L_MASK)
> > +#define ASPEED_ADC_LH_MASK  (ASPEED_ADC_L_MASK << 16 | 
> > ASPEED_ADC_L_MASK)
> > +
> > +static inline uint32_t update_channels(uint32_t current)
> > +{
> > +const uint32_t next = (current + 7) & 0x3ff;
> > +
> > +return (next << 16) | next;
> > +}
> > +
> > +static bool breaks_threshold(AspeedADCState *s, int ch_off)
> > +{
> > +const uint32_t a = ASPEED_ADC_L(s->channels[ch_off]);
> > +const uint32_t a_lower = ASPEED_ADC_L(s->bounds[2 * ch_off]);
> > +const uint32_t a_upper = ASPEED_ADC_H(s->bounds[2 * ch_off]);
> > +const uint32_t b = ASPEED_ADC_H(s->channels[ch_off]);
> > +const uint32_t b_lower = ASPEED_ADC_L(s->bounds[2 * ch_off + 1]);
> > +const uint32_t b_upper = ASPEED_ADC_H(s->bounds[2 * ch_off + 1]);
> > +
> > +return ((a < a_lower || a > a_upper)) ||
> > +   ((b < b_lower || b > b_upper));
> > +}
> > +
> > +static uint32_t read_channel_sample(AspeedADCState *s, int ch_off)
> > +{
> > +uint32_t ret;
> > +
> > +/* Poor man's sampling */
> > +ret = s->channels[ch_off];
> > +s->channels[ch_off] = update_channels(s->channels[ch_off]);
> > +
> > +if (breaks_threshold(s, ch_off)) {
> > +qemu_irq_raise(s->irq);
> > +}
> > +
> > +return ret;
> > +}
> > +
> > +#define TO_INDEX(addr, base) (((addr) - (base)) >> 2)
> > +
> > +static uint64_t aspeed_adc_read(void *opaque, hwaddr addr,
> > + unsigned int size)
> > +{
> > +AspeedADCState *s = ASPEED_ADC(opaque);
> > +uint64_t ret;
> > +
> > +switch (addr) {
> > +case 0x00:
> > +ret = s->engine_ctrl;
> > + 

Re: [Qemu-devel] [PATCH 0/2] hw/adc: Implement a basic Aspeed ADC model

2017-05-19 Thread Andrew Jeffery
On Fri, 2017-05-19 at 17:51 -0700, no-re...@patchew.org wrote:
> In file included from /tmp/qemu-test/src/hw/adc/aspeed_adc.c:15:0:
> /tmp/qemu-test/src/hw/adc/aspeed_adc.c: In function 'aspeed_adc_read':
> /tmp/qemu-test/src/hw/adc/aspeed_adc.c:106:34: error: format '%lx' expects 
> argument of type 'long unsigned int', but argument 3 has type 'hwaddr {aka 
> long long unsigned int}' [-Werror=format=]
>  qemu_log_mask(LOG_UNIMP, "%s: addr: 0x%lx, size: %u\n", __func__, 
> addr,
>   ^
> /tmp/qemu-test/src/include/qemu/log.h:94:22: note: in definition of macro 
> 'qemu_log_mask'
>  qemu_log(FMT, ## __VA_ARGS__);  \
>   ^~~
> /tmp/qemu-test/src/hw/adc/aspeed_adc.c: In function 'aspeed_adc_write':
> /tmp/qemu-test/src/hw/adc/aspeed_adc.c:162:34: error: format '%lu' expects 
> argument of type 'long unsigned int', but argument 3 has type 'hwaddr {aka 
> long long unsigned int}' [-Werror=format=]
>  qemu_log_mask(LOG_UNIMP, "%s: %lu\n", __func__, addr);
>   ^
> /tmp/qemu-test/src/include/qemu/log.h:94:22: note: in definition of macro 
> 'qemu_log_mask'
>  qemu_log(FMT, ## __VA_ARGS__);  \
>   ^~~
> cc1: all warnings being treated as errors
> /tmp/qemu-test/src/rules.mak:69: recipe for target 'hw/adc/aspeed_adc.o' 
> failed
> make[1]: *** [hw/adc/aspeed_adc.o] Error 1
> make[1]: *** Waiting for unfinished jobs
>   CC  aarch64-softmmu/hw/scsi/virtio-scsi-dataplane.o
> Makefile:327: recipe for target 'subdir-aarch64-softmmu' failed
> make: *** [subdir-aarch64-softmmu] Error 2
> make: *** Waiting for unfinished jobs
>   GEN x86_64-softmmu/qemu-system-x86_64.exe
> tests/docker/Makefile.include:118: recipe for target 'docker-run' failed
> make[1]: *** [docker-run] Error 2
> make[1]: Leaving directory '/var/tmp/patchew-tester-tmp-i73ef6w0/src'
> tests/docker/Makefile.include:149: recipe for target 
> 'docker-run-test-mingw@fedora' failed
> > make: *** [docker-run-test-mingw@fedora] Error 2
> === OUTPUT END ===
> 
> Test command exited with code: 2

I'll fix the format string issues in v2 along with any other issues
identified in review.

Separately, is it necessary for the bot to send the entirety of the
build output? Can we make it a bit smarter to send just the error with
some small amount of context? Maybe send the full log as an attachment?
Or host it and link to it from the email? It's a bit tedious having to
scroll through all that output to find the error at the bottom.

Cheers,

Andrew

signature.asc
Description: This is a digitally signed message part


[Qemu-devel] [PATCH 1/2] hw/adc: Add basic Aspeed ADC model

2017-05-19 Thread Andrew Jeffery
This model implements enough behaviour to do basic functionality tests
such as device initialisation and read out of dummy sample values. The
sample value generation strategy is similar to the STM ADC already in
the tree.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
 hw/adc/Makefile.objs|   1 +
 hw/adc/aspeed_adc.c | 246 
 include/hw/adc/aspeed_adc.h |  33 ++
 3 files changed, 280 insertions(+)
 create mode 100644 hw/adc/aspeed_adc.c
 create mode 100644 include/hw/adc/aspeed_adc.h

diff --git a/hw/adc/Makefile.objs b/hw/adc/Makefile.objs
index 3f6dfdedaec7..2bf9362ba3c4 100644
--- a/hw/adc/Makefile.objs
+++ b/hw/adc/Makefile.objs
@@ -1 +1,2 @@
 obj-$(CONFIG_STM32F2XX_ADC) += stm32f2xx_adc.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_adc.o
diff --git a/hw/adc/aspeed_adc.c b/hw/adc/aspeed_adc.c
new file mode 100644
index ..d08f1684f7bc
--- /dev/null
+++ b/hw/adc/aspeed_adc.c
@@ -0,0 +1,246 @@
+/*
+ * Aspeed ADC
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2017 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 "hw/adc/aspeed_adc.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+
+#define ASPEED_ADC_ENGINE_CTRL  0x00
+#define  ASPEED_ADC_ENGINE_CH_EN_MASK   0x
+#define   ASPEED_ADC_ENGINE_CH_EN(x)((BIT(x)) << 16)
+#define  ASPEED_ADC_ENGINE_INIT BIT(8)
+#define  ASPEED_ADC_ENGINE_AUTO_COMPBIT(5)
+#define  ASPEED_ADC_ENGINE_COMP BIT(4)
+#define  ASPEED_ADC_ENGINE_MODE_MASK0x000e
+#define   ASPEED_ADC_ENGINE_MODE_OFF(0b000 << 1)
+#define   ASPEED_ADC_ENGINE_MODE_STANDBY(0b001 << 1)
+#define   ASPEED_ADC_ENGINE_MODE_NORMAL (0b111 << 1)
+#define  ASPEED_ADC_ENGINE_EN   BIT(0)
+
+#define ASPEED_ADC_L_MASK   ((1 << 10) - 1)
+#define ASPEED_ADC_L(x) ((x) & ASPEED_ADC_L_MASK)
+#define ASPEED_ADC_H(x) (((x) >> 16) & ASPEED_ADC_L_MASK)
+#define ASPEED_ADC_LH_MASK  (ASPEED_ADC_L_MASK << 16 | ASPEED_ADC_L_MASK)
+
+static inline uint32_t update_channels(uint32_t current)
+{
+const uint32_t next = (current + 7) & 0x3ff;
+
+return (next << 16) | next;
+}
+
+static bool breaks_threshold(AspeedADCState *s, int ch_off)
+{
+const uint32_t a = ASPEED_ADC_L(s->channels[ch_off]);
+const uint32_t a_lower = ASPEED_ADC_L(s->bounds[2 * ch_off]);
+const uint32_t a_upper = ASPEED_ADC_H(s->bounds[2 * ch_off]);
+const uint32_t b = ASPEED_ADC_H(s->channels[ch_off]);
+const uint32_t b_lower = ASPEED_ADC_L(s->bounds[2 * ch_off + 1]);
+const uint32_t b_upper = ASPEED_ADC_H(s->bounds[2 * ch_off + 1]);
+
+return ((a < a_lower || a > a_upper)) ||
+   ((b < b_lower || b > b_upper));
+}
+
+static uint32_t read_channel_sample(AspeedADCState *s, int ch_off)
+{
+uint32_t ret;
+
+/* Poor man's sampling */
+ret = s->channels[ch_off];
+s->channels[ch_off] = update_channels(s->channels[ch_off]);
+
+if (breaks_threshold(s, ch_off)) {
+qemu_irq_raise(s->irq);
+}
+
+return ret;
+}
+
+#define TO_INDEX(addr, base) (((addr) - (base)) >> 2)
+
+static uint64_t aspeed_adc_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+AspeedADCState *s = ASPEED_ADC(opaque);
+uint64_t ret;
+
+switch (addr) {
+case 0x00:
+ret = s->engine_ctrl;
+break;
+case 0x04:
+ret = s->irq_ctrl;
+break;
+case 0x08:
+ret = s->vga_detect_ctrl;
+break;
+case 0x0c:
+ret = s->adc_clk_ctrl;
+break;
+case 0x10 ... 0x2e:
+ret = read_channel_sample(s, TO_INDEX(addr, 0x10));
+break;
+case 0x30 ... 0x6e:
+ret = s->bounds[TO_INDEX(addr, 0x30)];
+break;
+case 0x70 ... 0xae:
+ret = s->hysteresis[TO_INDEX(addr, 0x70)];
+break;
+case 0xc0:
+ret = s->irq_src;
+break;
+case 0xc4:
+ret = s->comp_trim;
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: addr: 0x%lx, size: %u\n", __func__, addr,
+size);
+ret = 0;
+break;
+}
+
+return ret;
+}
+
+static void aspeed_adc_write(void *opaque, hwaddr addr,
+   uint64_t val, unsigned int size)
+{
+AspeedADCState *s = ASPEED_ADC(opaque);
+
+switch (addr) {
+case 0x00:
+{
+uint32_t init;
+
+init = !!(val & ASPEED_ADC_ENGINE_EN);
+init *= ASPEED_ADC_ENGINE_INIT;
+
+val &= ~ASPEED_ADC_ENGINE_INIT;
+val |= init;
+}
+
+val &

[Qemu-devel] [PATCH 2/2] hw/arm: Integrate ADC model into Aspeed SoC

2017-05-19 Thread Andrew Jeffery
Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
 hw/arm/aspeed_soc.c | 15 +++
 include/hw/arm/aspeed_soc.h |  2 ++
 2 files changed, 17 insertions(+)

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 5c667d2c35b6..11f9588720d2 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -31,6 +31,7 @@
 #define ASPEED_SOC_VIC_BASE 0x1E6C
 #define ASPEED_SOC_SDMC_BASE0x1E6E
 #define ASPEED_SOC_SCU_BASE 0x1E6E2000
+#define ASPEED_SOC_ADC_BASE 0x1E6E9000
 #define ASPEED_SOC_SRAM_BASE0x1E72
 #define ASPEED_SOC_TIMER_BASE   0x1E782000
 #define ASPEED_SOC_WDT_BASE 0x1E785000
@@ -157,6 +158,10 @@ static void aspeed_soc_init(Object *obj)
 object_property_add_alias(obj, "hw-strap2", OBJECT(>scu),
   "hw-strap2", _abort);
 
+object_initialize(>adc, sizeof(s->adc), TYPE_ASPEED_ADC);
+object_property_add_child(obj, "adc", OBJECT(>adc), NULL);
+qdev_set_parent_bus(DEVICE(>adc), sysbus_get_default());
+
 object_initialize(>fmc, sizeof(s->fmc), sc->info->fmc_typename);
 object_property_add_child(obj, "fmc", OBJECT(>fmc), NULL);
 qdev_set_parent_bus(DEVICE(>fmc), sysbus_get_default());
@@ -256,6 +261,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 }
 sysbus_mmio_map(SYS_BUS_DEVICE(>scu), 0, ASPEED_SOC_SCU_BASE);
 
+/* ADC */
+object_property_set_bool(OBJECT(>adc), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>adc), 0, ASPEED_SOC_ADC_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(>adc), 0,
+qdev_get_gpio_in(DEVICE(>vic), 31));
+
 /* UART - attach an 8250 to the IO space as our UART5 */
 if (serial_hds[0]) {
 qemu_irq uart5 = qdev_get_gpio_in(DEVICE(>vic), uart_irqs[4]);
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index d16205c66b5f..3b4d66d30f08 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -15,6 +15,7 @@
 #include "hw/arm/arm.h"
 #include "hw/intc/aspeed_vic.h"
 #include "hw/misc/aspeed_scu.h"
+#include "hw/adc/aspeed_adc.h"
 #include "hw/misc/aspeed_sdmc.h"
 #include "hw/timer/aspeed_timer.h"
 #include "hw/i2c/aspeed_i2c.h"
@@ -37,6 +38,7 @@ typedef struct AspeedSoCState {
 AspeedTimerCtrlState timerctrl;
 AspeedI2CState i2c;
 AspeedSCUState scu;
+AspeedADCState adc;
 AspeedSMCState fmc;
 AspeedSMCState spi[ASPEED_SPIS_NUM];
 AspeedSDMCState sdmc;
-- 
2.9.3




[Qemu-devel] [PATCH 0/2] hw/adc: Implement a basic Aspeed ADC model

2017-05-19 Thread Andrew Jeffery
Hello,

This short series introduces a basic model for the Aspeed ADC and glues it into
the generic Aspeed SoC definition. The register interface is enhanced slightly
from the AST2400 to the AST2500, but in a backwards-compatible way by making
use of reserved bits. As such I haven't made any effort to differentiate the
two.

The addition of a basic ADC model allows the Aspeed SDK kernel to boot under
QEMU's ast2500-evb machine. The upstream kernel driver doesn't test the
initialisation bit before completing its probe(), and thus doesn't get stuck if
the bit is not set. This is in contrast to the SDK kernel which spins on the
initialisation bit, never making forward progress in the absence of the ADC
model.

Tested with both Aspeed's SDK kernel and upstream Linux.

Cheers,

Andrew

Andrew Jeffery (2):
  hw/adc: Add basic Aspeed ADC model
  hw/arm: Integrate ADC model into Aspeed SoC

 hw/adc/Makefile.objs|   1 +
 hw/adc/aspeed_adc.c | 246 
 hw/arm/aspeed_soc.c |  15 +++
 include/hw/adc/aspeed_adc.h |  33 ++
 include/hw/arm/aspeed_soc.h |   2 +
 5 files changed, 297 insertions(+)
 create mode 100644 hw/adc/aspeed_adc.c
 create mode 100644 include/hw/adc/aspeed_adc.h

-- 
2.9.3




Re: [Qemu-devel] [PATCH v4 8/8] arm: Add an RX8900 RTC to the ASpeed board

2017-01-03 Thread Andrew Jeffery
On Thu, 2016-12-15 at 16:48 +1100, Alastair D'Silva wrote:
> > From: Alastair D'Silva <alast...@d-silva.org>
> 
> Connect an RX8900 RTC to i2c12 of the AST2500 SOC at address 0x32
> 
> > Signed-off-by: Alastair D'Silva <alast...@d-silva.org>
> Signed-off-by: Chris Smart <ch...@distroguy.com>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed.c | 29 +
>  1 file changed, 29 insertions(+)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 40c1383..ef63fd0 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -26,6 +26,12 @@ static struct arm_boot_info aspeed_board_binfo = {
>  .nb_cpus = 1,
>  };
>  
> +typedef struct AspeedI2CDevice {
> +const char *type;
> +uint8_t address;
> +int bus;
> +} AspeedI2CDevice;
> +
>  typedef struct AspeedBoardState {
>  AspeedSoCState soc;
>  MemoryRegion ram;
> @@ -37,6 +43,7 @@ typedef struct AspeedBoardConfig {
>  const char *fmc_model;
>  const char *spi_model;
>  uint32_t num_cs;
> +const AspeedI2CDevice *i2c_devices;
>  } AspeedBoardConfig;
>  
>  enum {
> @@ -80,6 +87,11 @@ enum {
>  SCU_AST2500_HW_STRAP_ACPI_ENABLE |  \
>  SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
>  
> +
> +static const AspeedI2CDevice ast2500_i2c_devices[] = {
> +{"rx8900", 0x32, 11}
> +};
> +
>  static const AspeedBoardConfig aspeed_boards[] = {
>  [PALMETTO_BMC] = {
>  .soc_name  = "ast2400-a1",
> @@ -94,6 +106,7 @@ static const AspeedBoardConfig aspeed_boards[] = {
>  .fmc_model = "n25q256a",
>  .spi_model = "mx25l25635e",
>  .num_cs= 1,
> +.i2c_devices = ast2500_i2c_devices,
>  },
>  [ROMULUS_BMC]  = {
>  .soc_name  = "ast2500-a1",
> @@ -104,6 +117,7 @@ static const AspeedBoardConfig aspeed_boards[] = {
>  },
>  };
>  
> +
>  static void aspeed_board_init_flashes(AspeedSMCState *s, const char 
> *flashtype,
>    Error **errp)
>  {
> @@ -130,6 +144,19 @@ static void aspeed_board_init_flashes(AspeedSMCState *s, 
> const char *flashtype,
>  }
>  }
>  
> +static void aspeed_i2c_init(AspeedBoardState *bmc,
> +const AspeedBoardConfig *cfg)
> +{
> +AspeedSoCState *soc = >soc;
> +const AspeedI2CDevice *dev;
> +
> +for (dev = cfg->i2c_devices; dev != NULL && dev->type != NULL; dev++) {
> +I2CBus *i2c_bus = aspeed_i2c_get_bus((DeviceState *)>i2c,
> + dev->bus);
> +(void)i2c_create_slave(i2c_bus, dev->type, dev->address);
> +}
> +}
> +
>  static void aspeed_board_init(MachineState *machine,
>    const AspeedBoardConfig *cfg)
>  {
> @@ -174,6 +201,8 @@ static void aspeed_board_init(MachineState *machine,
>  aspeed_board_binfo.ram_size = ram_size;
>  aspeed_board_binfo.loader_start = sc->info->sdram_base;
>  
> +aspeed_i2c_init(bmc, cfg);
> +
>  arm_load_kernel(ARM_CPU(first_cpu), _board_binfo);
>  }
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v4 7/8] tests: Test all implemented RX8900 functionality

2017-01-03 Thread Andrew Jeffery
Hi Alastair,

Again, small comments below.

On Thu, 2016-12-15 at 16:48 +1100, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> 
> > Signed-off-by: Alastair D'Silva 
> ---
>  tests/Makefile.include |   2 +
>  tests/rx8900-test.c| 882 
> +
>  2 files changed, 884 insertions(+)
>  create mode 100644 tests/rx8900-test.c
> 
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index e98d3b6..e52e355 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -300,6 +300,7 @@ check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
>  
>  check-qtest-arm-y = tests/tmp105-test$(EXESUF)
>  check-qtest-arm-y += tests/ds1338-test$(EXESUF)
> +check-qtest-arm-y += tests/rx8900-test$(EXESUF)
>  check-qtest-arm-y += tests/m25p80-test$(EXESUF)
>  gcov-files-arm-y += hw/misc/tmp105.c
>  check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
> @@ -637,6 +638,7 @@ tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o 
> \
>  tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
>  tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
>  tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
> +tests/rx8900-test$(EXESUF): tests/rx8900-test.o $(libqos-imx-obj-y)
>  tests/m25p80-test$(EXESUF): tests/m25p80-test.o
>  tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
>  tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y)
> diff --git a/tests/rx8900-test.c b/tests/rx8900-test.c
> new file mode 100644
> index 000..1769659
> --- /dev/null
> +++ b/tests/rx8900-test.c
> @@ -0,0 +1,882 @@
> +/*
> + * QTest testcase for the Epson RX8900SA/CE RTC
> + *
> + * Copyright (c) 2016 IBM Corporation
> + * Authors:
> > + *  Alastair D'Silva 
> + *
> + * 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 "hw/timer/rx8900_regs.h"
> +#include "libqtest.h"
> +#include "libqos/i2c.h"
> +#include "qemu/timer.h"
> +
> +#define IMX25_I2C_0_BASE 0x43F8
> +#define RX8900_TEST_ID "rx8900-test"
> +#define RX8900_ADDR 0x32
> +#define RX8900_INTERRUPT_OUT "rx8900-interrupt-out"
> +#define RX8900_FOUT_ENABLE "rx8900-fout-enable"
> +#define RX8900_FOUT "rx8900-fout"
> +
> +static I2CAdapter *i2c;
> +static uint8_t addr;
> +
> +static inline uint8_t bcd2bin(uint8_t x)
> +{
> +return (x & 0x0f) + (x >> 4) * 10;
> +}
> +
> +static inline uint8_t bin2bcd(uint8_t x)
> +{
> +return (x / 10 << 4) | (x % 10);
> +}
> +
> +static void qmp_rx8900_set_temperature(const char *id, double value)
> +{
> +QDict *response;
> +
> +response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
> +   "'property': 'temperature', 'value': %f } }", id, value);
> +g_assert(qdict_haskey(response, "return"));
> +QDECREF(response);
> +}
> +
> +static void qmp_rx8900_set_voltage(const char *id, double value)
> +{
> +QDict *response;
> +
> +response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
> +   "'property': 'voltage', 'value': %f } }", id, value);
> +g_assert(qdict_haskey(response, "return"));
> +QDECREF(response);
> +}
> +
> +/**
> + * Read an RX8900 register
> + * @param reg the address of the register
> + * @return the value of the register
> + */
> +static uint8_t read_register(RX8900Addresses reg)
> +{
> +uint8_t val;
> +uint8_t reg_address = (uint8_t)reg;
> +
> +i2c_send(i2c, addr, _address, 1);
> +i2c_recv(i2c, addr, , 1);
> +
> +return val;
> +}
> +
> +/**
> + * Write to an RX8900 register
> + * @param reg the address of the register
> + * @param val the value to write
> + */
> +static uint8_t write_register(RX8900Addresses reg, uint8_t val)
> +{
> +uint8_t buf[2];
> +
> +buf[0] = reg;
> +buf[1] = val;
> +
> +i2c_send(i2c, addr, buf, 2);
> +
> +return val;
> +}
> +
> +/**
> + * Set bits in a register
> + * @param reg the address of the register
> + * @param mask a mask of the bits to set
> + */
> +static void set_bits_in_register(RX8900Addresses reg, uint8_t mask)
> +{
> +uint8_t value = read_register(reg);
> +value |= mask;
> +write_register(reg, value);
> +}
> +
> +/**
> + * Clear bits in a register
> + * @param reg the address of the register
> + * @param mask a mask of the bits to set
> + */
> +static void clear_bits_in_register(RX8900Addresses reg, uint8_t mask)
> +{
> +uint8_t value = read_register(reg);
> +value &= ~mask;
> +write_register(reg, value);
> +}
> +
> +/**
> + * Read a number of sequential RX8900 registers
> + * @param reg the address of the first register
> + * @param buf (out) an output buffer to stash the register values
> + * @param count the number of registers to read
> + */
> +static void read_registers(RX8900Addresses reg, uint8_t *buf, uint8_t count)
> +{

Re: [Qemu-devel] [PATCH v4 6/8] hw/timer: Add Epson RX8900 RTC support

2017-01-03 Thread Andrew Jeffery
Hi Alastair,

I have some mostly minor comments below.

On Thu, 2016-12-15 at 16:48 +1100, Alastair D'Silva wrote:
> > From: Alastair D'Silva 
> 
> This patch adds support for the Epson RX8900 I2C RTC.
> 
> The following chip features are implemented:
>  - RTC (wallclock based, ptimer 10x oversampling to pick up
> wallclock transitions)
>  - Time update interrupt (per second/minute, wallclock based)
>  - Alarms (wallclock based)
>  - Temperature (set via a property)
>  - Countdown timer (emulated clock via ptimer)
>  - FOUT via GPIO (emulated clock via ptimer)
> 
> The following chip features are unimplemented:
>  - Low voltage detection
>  - i2c timeout
> 
> The implementation exports the following named GPIOs:
> rx8900-interrupt-out
> rx8900-fout-enable
> rx8900-fout
> 
> > Signed-off-by: Alastair D'Silva 
> > Signed-off-by: Chris Smart 
> ---
>  default-configs/arm-softmmu.mak |   1 +
>  hw/timer/Makefile.objs  |   2 +
>  hw/timer/rx8900.c   | 912 
> 
>  hw/timer/rx8900_regs.h  | 141 +++
>  hw/timer/trace-events   |  31 ++
>  5 files changed, 1087 insertions(+)
>  create mode 100644 hw/timer/rx8900.c
>  create mode 100644 hw/timer/rx8900_regs.h
> 
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index 6de3e16..adb600e 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -29,6 +29,7 @@ CONFIG_SMC91C111=y
>  CONFIG_ALLWINNER_EMAC=y
>  CONFIG_IMX_FEC=y
>  CONFIG_DS1338=y
> +CONFIG_RX8900=y
>  CONFIG_PFLASH_CFI01=y
>  CONFIG_PFLASH_CFI02=y
>  CONFIG_MICRODRIVE=y
> diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
> index 7ba8c23..fa028ac 100644
> --- a/hw/timer/Makefile.objs
> +++ b/hw/timer/Makefile.objs
> @@ -3,6 +3,7 @@ common-obj-$(CONFIG_ARM_MPTIMER) += arm_mptimer.o
>  common-obj-$(CONFIG_A9_GTIMER) += a9gtimer.o
>  common-obj-$(CONFIG_CADENCE) += cadence_ttc.o
>  common-obj-$(CONFIG_DS1338) += ds1338.o
> +common-obj-$(CONFIG_RX8900) += rx8900.o
>  common-obj-$(CONFIG_HPET) += hpet.o
>  common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
>  common-obj-$(CONFIG_M48T59) += m48t59.o
> @@ -17,6 +18,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o
>  common-obj-$(CONFIG_IMX) += imx_gpt.o
>  common-obj-$(CONFIG_LM32) += lm32_timer.o
>  common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
> +common-obj-$(CONFIG_RX8900) += rx8900.o
>  
>  obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
>  obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o
> diff --git a/hw/timer/rx8900.c b/hw/timer/rx8900.c
> new file mode 100644
> index 000..cb1a2c8
> --- /dev/null
> +++ b/hw/timer/rx8900.c
> @@ -0,0 +1,912 @@
> +/*
> + * Epson RX8900SA/CE Realtime Clock Module
> + *
> + * Copyright (c) 2016 IBM Corporation
> + * Authors:
> > + *  Alastair D'Silva 
> > + *  Chris Smart 
> + *
> + * This code is licensed under the GPL version 2 or later.  See
> + * the COPYING file in the top-level directory.
> + *
> + * Datasheet available at:
> + *  https://support.epson.biz/td/api/doc_check.php?dl=app_RX8900CE=en
> + *
> + * Not implemented:
> + *  Implement i2c timeout
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +#include "hw/i2c/i2c.h"
> +#include "hw/timer/rx8900_regs.h"
> +#include "hw/ptimer.h"
> +#include "qemu/main-loop.h"
> +#include "qemu/bcd.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "qapi/visitor.h"
> +#include "trace.h"
> +
> +#define TYPE_RX8900 "rx8900"
> +#define RX8900(obj) OBJECT_CHECK(RX8900State, (obj), TYPE_RX8900)
> +
> +typedef struct RX8900State {
> +I2CSlave parent_obj;
> +
> +ptimer_state *sec_timer; /* triggered once per second */
> +ptimer_state *fout_timer;
> +ptimer_state *countdown_timer;
> +bool fout_state;
> +int64_t offset;
> +uint8_t weekday; /* Saved for deferred offset calculation, 0-6 */
> +uint8_t wday_offset;
> +uint8_t nvram[RX8900_NVRAM_SIZE];
> +int32_t nvram_offset; /* Wrapped to stay within RX8900_NVRAM_SIZE */
> +bool addr_byte;
> +uint8_t last_interrupt_seconds; /* The last time the second timer ticked 
> */
> +/* the last minute the timer update interrupt was triggered (if enabled) 
> */
> +uint8_t last_update_interrupt_minutes;
> +double supply_voltage;
> +qemu_irq interrupt_pin;
> +qemu_irq fout_pin;
> +} RX8900State;
> +
> +static const VMStateDescription vmstate_rx8900 = {
> +.name = "rx8900",
> +.version_id = 1,
> +.minimum_version_id = 1,
> +.fields = (VMStateField[]) {
> +VMSTATE_I2C_SLAVE(parent_obj, RX8900State),
> +VMSTATE_PTIMER(sec_timer, RX8900State),
> +VMSTATE_PTIMER(fout_timer, RX8900State),
> +VMSTATE_PTIMER(countdown_timer, RX8900State),
> +VMSTATE_BOOL(fout_state, RX8900State),
> +VMSTATE_INT64(offset, RX8900State),
> +

Re: [Qemu-devel] [PATCH for-2.9 28/30] aspeed: add a watchdog controller

2016-11-29 Thread Andrew Jeffery
On Tue, 2016-11-29 at 16:44 +0100, Cédric Le Goater wrote:
> This enables reboot of a guest from U-Boot and Linux.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>
> Reviewed-by: Joel Stanley <j...@jms.id.au>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed_soc.c | 13 +
>  include/hw/arm/aspeed_soc.h |  2 ++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 4fb777e6df6e..6df76382f007 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -31,6 +31,7 @@
>  #define ASPEED_SOC_SCU_BASE 0x1E6E2000
>  #define ASPEED_SOC_SRAM_BASE0x1E72
>  #define ASPEED_SOC_TIMER_BASE   0x1E782000
> +#define ASPEED_SOC_WDT_BASE 0x1E785000
>  #define ASPEED_SOC_I2C_BASE 0x1E78A000
>  
>  static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
> @@ -170,6 +171,10 @@ static void aspeed_soc_init(Object *obj)
>   sc->info->silicon_rev);
>  object_property_add_alias(obj, "ram-size", OBJECT(>sdmc),
>    "ram-size", _abort);
> +
> +object_initialize(>wdt, sizeof(s->wdt), TYPE_ASPEED_WDT);
> +object_property_add_child(obj, "wdt", OBJECT(>wdt), NULL);
> +qdev_set_parent_bus(DEVICE(>wdt), sysbus_get_default());
>  }
>  
>  static void aspeed_soc_realize(DeviceState *dev, Error **errp)
> @@ -289,6 +294,14 @@ static void aspeed_soc_realize(DeviceState *dev,
> Error **errp)
>  return;
>  }
>  sysbus_mmio_map(SYS_BUS_DEVICE(>sdmc), 0,
> ASPEED_SOC_SDMC_BASE);
> +
> +/* Watch dog */
> +object_property_set_bool(OBJECT(>wdt), true, "realized",
> );
> +if (err) {
> +error_propagate(errp, err);
> +return;
> +}
> +sysbus_mmio_map(SYS_BUS_DEVICE(>wdt), 0,
> ASPEED_SOC_WDT_BASE);
>  }
>  
>  static void aspeed_soc_class_init(ObjectClass *oc, void *data)
> diff --git a/include/hw/arm/aspeed_soc.h
> b/include/hw/arm/aspeed_soc.h
> index 1ab5deaa0813..dbec0c159885 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -19,6 +19,7 @@
>  #include "hw/timer/aspeed_timer.h"
>  #include "hw/i2c/aspeed_i2c.h"
>  #include "hw/ssi/aspeed_smc.h"
> +#include "hw/watchdog/wdt_aspeed.h"
>  
>  #define ASPEED_SPIS_NUM  2
>  
> @@ -37,6 +38,7 @@ typedef struct AspeedSoCState {
>  AspeedSMCState fmc;
>  AspeedSMCState spi[ASPEED_SPIS_NUM];
>  AspeedSDMCState sdmc;
> +AspeedWDTState wdt;
>  } AspeedSoCState;
>  
>  #define TYPE_ASPEED_SOC "aspeed-soc"

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 4/4] arm: Add an RX8900 RTC to the ASpeed board

2016-11-23 Thread Andrew Jeffery
On Wed, 2016-11-23 at 09:48 +0100, Cédric Le Goater wrote:
> On 11/23/2016 01:46 AM, Alastair D'Silva wrote:
> > On Tue, 2016-11-22 at 17:56 +0100, Cédric Le Goater wrote:
> > > On 11/17/2016 05:36 AM, Alastair D'Silva wrote:
> > > > 
> > > > > > > > From: Alastair D'Silva 
> > > > 
> > > > Connect an RX8900 RTC to i2c12 of the AST2500 SOC at address 0x32
> > > 
> > > If this is a board device, we should include it under a machine
> > > routine.
> > > 
> > > Is that for the palmetto ? The ast2500 does not have a RTC.
> > > 
> > > Thanks,
> > > 
> > > C. 
> > 
> > Ok
> 
>  
> I suppose we could change aspeed_board_init() to return 
> a AspeedSoCState* and use the soc object in the specific 
> _init routines to add devices. 
> 
> Andrew, what is your opinion on that ? 

I see the I2C bus configuration as a declarative problem. In a similar
vein we already have AspeedBoardConfig, so I think we should try to
describe the buses and attached devices there. That way we can have a
generic aspeed_i2c_bus_init() routine that we call inside
aspeed_board_init().

This would avoid encoding the buses and their slaves in the board-
specific init code.

Is that a reasonable alternative? I agree that we need to use a
different approach to that which the current patch is using.

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 2/4] hw/misc: add a TMP42{1, 2, 3} device model

2016-11-14 Thread Andrew Jeffery
On Mon, 2016-11-14 at 08:14 +0100, Cédric Le Goater wrote:
> > Given the starting point of the tmp105 code the patch looks okay, but I
> > was a bit thrown by the use of the 'len' member as what I'd consider an
> > index. For instance we reset len to zero in tmp421_event() after
> > populating buf, and then the data in buf is presumably sent out on a
> > recv transaction which again starts incrementing len. len is also
> > incremented when we don't interact with buf, e.g. when we instead
> > assign to pointer. It feels like it could be prone to bugs, and
> > 'cb5ef3fa1871 tmp105: Fix I2C protocol bug' suggests that might not be
> > an unreasonable feeling.
> > 
> > But given the code already exists in tmp105 maybe it's fine?
> 
> So, I took my time to check this but yes, I think the code is fine.

Yes, from memory it was okay, just not as obvious as I'd hoped it to
be.

> 
> However, tmp421 does not need to support 2 bytes writes so we can
> simplify tmp421_tx() :
> 
> static int tmp421_tx(I2CSlave *i2c, uint8_t data)
> {
>     TMP421State *s = TMP421(i2c);
> 
>     if (s->len == 0) {
>     /* first byte is the register pointer for a read or write
>  * operation */
>     s->pointer = data;
>     s->len++;
>     } else if (s->len == 1) {
>     /* second byte is the data to write. The device only supports
>  * one byte writes */
>     s->buf[0] = data;
>     tmp421_write(s);
>     }
> 
>     return 0;
> }
> 
> and tmp421 needs to support 2 bytes reads, so we need to extend a bit 
> tmp421_read() when the temperatures are are. Linux does not use it 
> so I guess we should use a command line tool to test.

Okay.

> 
> I will send an updated patch for the TMP42{1,2,3} device with a larger 
> patchset I am working on for Aspeed support. That is for 2.9.
> 

Okay, I'll review again then.

Thanks,

Andrew

> Thanks,
> 
> C. 

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 6/6] aspeed: add support for the SMC segment registers

2016-10-04 Thread Andrew Jeffery
On Tue, 2016-09-27 at 13:57 +0200, Cédric Le Goater wrote:
> The SMC controller on the Aspeed SoC has a set of registers to
> configure the mapping of each flash module in the SoC address
> space. Writing to these registers triggers a remap of the memory
> region and the spec requires a certain number of checks before doing
> so.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/ssi/aspeed_smc.c | 135 
> ++--
>  1 file changed, 130 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index ecf39ccfde0e..6e8403ebc246 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -79,10 +79,10 @@
>  
>  /* CEx Segment Address Register */
>  #define R_SEG_ADDR0   (0x30 / 4)
> -#define   SEG_SIZE_SHIFT   24   /* 8MB units */
> -#define   SEG_SIZE_MASK0x7f
> +#define   SEG_END_SHIFT24   /* 8MB units */
> +#define   SEG_END_MASK 0xff

Was this a bug? The top bit is reserved as 0 in the 2500 datasheet, but
valid as your change suggests in the 2400.

>  #define   SEG_START_SHIFT  16   /* address bit [A29-A23] */
> -#define   SEG_START_MASK   0x7f
> +#define   SEG_START_MASK   0xff

As above.

>  #define R_SEG_ADDR1   (0x34 / 4)
>  #define R_SEG_ADDR2   (0x38 / 4)
>  #define R_SEG_ADDR3   (0x3C / 4)
> @@ -135,8 +135,7 @@
>  /*
>   * Default segments mapping addresses and size for each slave per
>   * controller. These can be changed when board is initialized with the
> - * Segment Address Registers but they don't seem do be used on the
> - * field.
> + * Segment Address Registers.
>   */
>  static const AspeedSegments aspeed_segments_legacy[] = {
>  { 0x1000, 32 * 1024 * 1024 },
> @@ -191,6 +190,118 @@ static const AspeedSMCController controllers[] = {
>    ASPEED_SOC_SPI2_FLASH_BASE, 0x800 },
>  };
>  
> +/*
> + * The Segment Register uses a 8MB unit to encode the start address
> + * and the end address of the mapping window of a flash SPI slave :
> + *
> + *| byte 1 | byte 2 | byte 3 | byte 4 |
> + *+++++
> + *|  end   |  start |   0|   0|
> + *
> + */
> +static inline uint32_t aspeed_smc_segment_to_reg(const AspeedSegments *seg)
> +{
> +uint32_t reg = 0;
> +reg |= ((seg->addr >> 23) & SEG_START_MASK) << SEG_START_SHIFT;
> +reg |= (((seg->addr + seg->size) >> 23) & SEG_END_MASK) << SEG_END_SHIFT;
> +return reg;
> +}
> +
> +static inline void aspeed_smc_reg_to_segment(uint32_t reg, AspeedSegments 
> *seg)
> +{
> +seg->addr = ((reg >> SEG_START_SHIFT) & SEG_START_MASK) << 23;
> +seg->size = (((reg >> SEG_END_SHIFT) & SEG_END_MASK) << 23) - seg->addr;
> +}
> +
> +static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
> + const AspeedSegments *new,
> + int cs)
> +{
> +AspeedSegments seg;
> +int i;
> +
> +for (i = 0; i < s->ctrl->max_slaves; i++) {
> +if (i == cs) {
> +continue;
> +}
> +
> +aspeed_smc_reg_to_segment(s->regs[R_SEG_ADDR0 + i], );
> +
> +if (new->addr + new->size > seg.addr &&
> +new->addr < seg.addr + seg.size) {
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment CS%d [ 0x%"
> +  HWADDR_PRIx" - 0x%"HWADDR_PRIx" ] overlaps with "
> +  "CS%d [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
> +  s->ctrl->name, cs, new->addr, new->addr + 
> new->size,
> +  i, seg.addr, seg.addr + seg.size);
> +return true;
> +}
> +}
> +return false;
> +}
> +
> +static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
> + uint64_t new)
> +{
> +AspeedSMCFlash *fl = >flashes[cs];
> +AspeedSegments seg;
> +
> +aspeed_smc_reg_to_segment(new, );
> +
> +/* The start address of CS0 is read-only */
> +if (cs == 0 && seg.addr != s->ctrl->flash_window_base) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: Tried to change CS0 start address to 0x%"
> +  HWADDR_PRIx "\n", s->ctrl->name, seg.addr);
> +return;
> +}
> +
> +/*
> + * The e

Re: [Qemu-devel] [PATCH 5/6] aspeed: create mapping regions for the maximum number of slaves

2016-10-04 Thread Andrew Jeffery
On Tue, 2016-09-27 at 13:57 +0200, Cédric Le Goater wrote:
> The SMC controller on the Aspeed SoC has a set of registers to
> configure the mapping of each flash module in the SoC address
> space. These mapping windows are configurable even though no SPI slave
> is attached to the controller.
> 
> Also rewrite a bit the comments in the code on this topic.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/ssi/aspeed_smc.c | 16 +---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index 21943f4e5dfa..ecf39ccfde0e 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -417,12 +417,15 @@ static void aspeed_smc_realize(DeviceState *dev, Error 
> **errp)
>  
>  aspeed_smc_reset(dev);
>  
> +/* The memory region for the controller registers */
>  memory_region_init_io(>mmio, OBJECT(s), _smc_ops, s,
>    s->ctrl->name, ASPEED_SMC_R_MAX * 4);
>  sysbus_init_mmio(sbd, >mmio);
>  
>  /*
> - * Memory region where flash modules are remapped
> + * The container memory region representing the address space
> + * window in which the flash modules are mapped. The size and
> + * address depends on the SoC model and controller type.
>   */
>  snprintf(name, sizeof(name), "%s.flash", s->ctrl->name);
>  
> @@ -431,9 +434,16 @@ static void aspeed_smc_realize(DeviceState *dev, Error 
> **errp)
>    s->ctrl->flash_window_size);
>  sysbus_init_mmio(sbd, >mmio_flash);
>  
> -s->flashes = g_new0(AspeedSMCFlash, s->num_cs);
> +s->flashes = g_new0(AspeedSMCFlash, s->ctrl->max_slaves);
>  
> -for (i = 0; i < s->num_cs; ++i) {
> +/*
> + * Let's create a sub memory region for each possible slave. All
> + * have a configurable memory segment in the overall flash mapping
> + * window of the controller but, there is not necessarily a flash
> + * module behind to handle the memory accesses. This depends on
> + * the board configuration.
> + */
> +for (i = 0; i < s->ctrl->max_slaves; ++i) {
>  AspeedSMCFlash *fl = >flashes[i];
>  
>  snprintf(name, sizeof(name), "%s.%d", s->ctrl->name, i);

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 4/6] aspeed: add support for the AST2500 SoC SMC controllers

2016-10-04 Thread Andrew Jeffery
On Tue, 2016-09-27 at 13:57 +0200, Cédric Le Goater wrote:
> The SMC controllers on the Aspeed AST2500 SoC are very similar to the
> ones found on the AST2400. The differences are on the number of
> supported flash modules and their default mappings in the SoC address
> space.
> 
> The Aspeed AST2500 has one SPI controller for the BMC firmware and two
> for the host firmware. All controllers have now the same set of
> registers compatible with the AST2400 FMC controller and the legacy
> 'SMC' controller is fully gone.
> 
> We keep the FMC object to act as the BMC SPI controller and add a new
> SPI controller for the host. We also have to introduce new type names
> to handle the differences in the flash modules memory mappping.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed_soc.c | 21 +++--
>  hw/ssi/aspeed_smc.c | 28 +++-
>  include/hw/arm/aspeed_soc.h |  2 ++
>  3 files changed, 44 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index b3103f337374..e14f5c217eab 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -25,6 +25,7 @@
>  #define ASPEED_SOC_IOMEM_BASE   0x1E60
>  #define ASPEED_SOC_FMC_BASE 0x1E62
>  #define ASPEED_SOC_SPI_BASE 0x1E63
> +#define ASPEED_SOC_SPI2_BASE0x1E631000
>  #define ASPEED_SOC_VIC_BASE 0x1E6C
>  #define ASPEED_SOC_SDMC_BASE0x1E6E
>  #define ASPEED_SOC_SCU_BASE 0x1E6E2000
> @@ -38,16 +39,23 @@ static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 
> 38, 39, };
>  #define AST2500_SDRAM_BASE   0x8000
>  
>  static const hwaddr aspeed_soc_ast2400_spi_bases[] = { ASPEED_SOC_SPI_BASE };
> +static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
>  
> -static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE };
> +static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE,
> +   ASPEED_SOC_SPI2_BASE};
> +static const char *aspeed_soc_ast2500_typenames[] = {
> +"aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" };
>  
>  static const AspeedSoCInfo aspeed_socs[] = {
>  { "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
> -  1, aspeed_soc_ast2400_spi_bases },
> +  1, aspeed_soc_ast2400_spi_bases,
> +  "aspeed.smc.fmc", aspeed_soc_ast2400_typenames },
>  { "ast2400","arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
> -  1, aspeed_soc_ast2400_spi_bases },
> +  1, aspeed_soc_ast2400_spi_bases,
> + "aspeed.smc.fmc", aspeed_soc_ast2400_typenames },
>  { "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE,
> -  1, aspeed_soc_ast2500_spi_bases },
> +  2, aspeed_soc_ast2500_spi_bases,
> +  "aspeed.smc.ast2500-fmc", aspeed_soc_ast2500_typenames },
>  };
>  
>  /*
> @@ -105,12 +113,13 @@ static void aspeed_soc_init(Object *obj)
>  object_property_add_alias(obj, "hw-strap2", OBJECT(>scu),
>    "hw-strap2", _abort);
>  
> -object_initialize(>fmc, sizeof(s->fmc), "aspeed.smc.fmc");
> +object_initialize(>fmc, sizeof(s->fmc), sc->info->fmc_typename);
>  object_property_add_child(obj, "fmc", OBJECT(>fmc), NULL);
>  qdev_set_parent_bus(DEVICE(>fmc), sysbus_get_default());
>  
>  for (i = 0; i < sc->info->spis_num; i++) {
> -object_initialize(>spi[i], sizeof(s->spi[i]), "aspeed.smc.spi");
> +object_initialize(>spi[i], sizeof(s->spi[i]),
> +  sc->info->spi_typename[i]);
>  object_property_add_child(obj, "spi", OBJECT(>spi[i]), NULL);
>  qdev_set_parent_bus(DEVICE(>spi[i]), sysbus_get_default());
>  }
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index 84c18299de11..21943f4e5dfa 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -130,6 +130,7 @@
>  #define ASPEED_SOC_SMC_FLASH_BASE   0x1000
>  #define ASPEED_SOC_FMC_FLASH_BASE   0x2000
>  #define ASPEED_SOC_SPI_FLASH_BASE   0x3000
> +#define ASPEED_SOC_SPI2_FLASH_BASE  0x3800
>  
>  /*
>   * Default segments mapping addresses and size for each slave per
> @@ -142,7 +143,7 @@ static const AspeedSegments aspeed_segments_legacy[] = {
>  };
>  
>  static const AspeedSegments aspeed_segments_fmc[] = {
> -  

Re: [Qemu-devel] [PATCH 3/6] aspeed: extend the number of host SPI controllers

2016-10-04 Thread Andrew Jeffery
On Tue, 2016-09-27 at 13:57 +0200, Cédric Le Goater wrote:
> The AST2500 SoC has two. Let's prepare ground for the next changes
> which will add the required definitions for the second host SPI
> controller.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed.c |  2 +-
>  hw/arm/aspeed_soc.c | 44 +---
>  include/hw/arm/aspeed_soc.h |  6 +-
>  3 files changed, 35 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 4bb33cbb5e70..c7206fda6d85 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -129,7 +129,7 @@ static void aspeed_board_init(MachineState *machine,
> _abort);
>  
>  aspeed_board_init_flashes(>soc.fmc, "n25q256a", _abort);
> -aspeed_board_init_flashes(>soc.spi, "mx25l25635e", _abort);
> +aspeed_board_init_flashes(>soc.spi[0], "mx25l25635e", _abort);
>  
>  aspeed_board_binfo.kernel_filename = machine->kernel_filename;
>  aspeed_board_binfo.initrd_filename = machine->initrd_filename;
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 80ad7322bde2..b3103f337374 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -37,10 +37,17 @@ static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 
> 38, 39, };
>  #define AST2400_SDRAM_BASE   0x4000
>  #define AST2500_SDRAM_BASE   0x8000
>  
> +static const hwaddr aspeed_soc_ast2400_spi_bases[] = { ASPEED_SOC_SPI_BASE };
> +
> +static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE };
> +
>  static const AspeedSoCInfo aspeed_socs[] = {
> -{ "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE },
> -{ "ast2400","arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE },
> -{ "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE },
> +{ "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
> +  1, aspeed_soc_ast2400_spi_bases },
> +{ "ast2400","arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE,
> +  1, aspeed_soc_ast2400_spi_bases },
> +{ "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE,
> +  1, aspeed_soc_ast2500_spi_bases },
>  };
>  
>  /*
> @@ -72,6 +79,7 @@ static void aspeed_soc_init(Object *obj)
>  {
>  AspeedSoCState *s = ASPEED_SOC(obj);
>  AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
> +int i;
>  
>  s->cpu = cpu_arm_init(sc->info->cpu_model);
>  
> @@ -101,9 +109,11 @@ static void aspeed_soc_init(Object *obj)
>  object_property_add_child(obj, "fmc", OBJECT(>fmc), NULL);
>  qdev_set_parent_bus(DEVICE(>fmc), sysbus_get_default());
>  
> -object_initialize(>spi, sizeof(s->spi), "aspeed.smc.spi");
> -object_property_add_child(obj, "spi", OBJECT(>spi), NULL);
> -qdev_set_parent_bus(DEVICE(>spi), sysbus_get_default());
> +for (i = 0; i < sc->info->spis_num; i++) {
> +object_initialize(>spi[i], sizeof(s->spi[i]), "aspeed.smc.spi");
> +object_property_add_child(obj, "spi", OBJECT(>spi[i]), NULL);
> +qdev_set_parent_bus(DEVICE(>spi[i]), sysbus_get_default());
> +}
>  
>  object_initialize(>sdmc, sizeof(s->sdmc), TYPE_ASPEED_SDMC);
>  object_property_add_child(obj, "sdmc", OBJECT(>sdmc), NULL);
> @@ -118,6 +128,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
> **errp)
>  {
>  int i;
>  AspeedSoCState *s = ASPEED_SOC(dev);
> +AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
>  Error *err = NULL, *local_err = NULL;
>  
>  /* IO space */
> @@ -190,16 +201,19 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
> **errp)
> qdev_get_gpio_in(DEVICE(>vic), 19));
>  
>  /* SPI */
> -object_property_set_int(OBJECT(>spi), 1, "num-cs", );
> -object_property_set_bool(OBJECT(>spi), true, "realized", _err);
> -error_propagate(, local_err);
> -if (err) {
> -error_propagate(errp, err);
> -return;
> +for (i = 0; i < sc->info->spis_num; i++) {
> +object_property_set_int(OBJECT(>spi[i]), 1, "num-cs", );
> +object_property_set_bool(OBJECT(>spi[i]), true, "realized",
> + _err);
> +error_propagate(, local_err);
&

Re: [Qemu-devel] [PATCH 2/6] aspeed: move the flash module mapping address under the controller definition

2016-10-04 Thread Andrew Jeffery
On Tue, 2016-09-27 at 13:57 +0200, Cédric Le Goater wrote:
> This will ease the definition of the new controllers for the AST2500
> SoC and also ease the support of the segment registers, which provide
> a way to reconfigure the mapping window of each slave.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed_soc.c |  9 -
>  hw/ssi/aspeed_smc.c | 15 +++
>  include/hw/ssi/aspeed_smc.h |  3 ++-
>  3 files changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 479c0d2039d9..80ad7322bde2 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -31,9 +31,6 @@
>  #define ASPEED_SOC_TIMER_BASE   0x1E782000
>  #define ASPEED_SOC_I2C_BASE 0x1E78A000
>  
> -#define ASPEED_SOC_FMC_FLASH_BASE   0x2000
> -#define ASPEED_SOC_SPI_FLASH_BASE   0x3000
> -
>  static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
>  static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
>  
> @@ -187,7 +184,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
> **errp)
>  return;
>  }
>  sysbus_mmio_map(SYS_BUS_DEVICE(>fmc), 0, ASPEED_SOC_FMC_BASE);
> -sysbus_mmio_map(SYS_BUS_DEVICE(>fmc), 1, ASPEED_SOC_FMC_FLASH_BASE);
> +sysbus_mmio_map(SYS_BUS_DEVICE(>fmc), 1,
> +s->fmc.ctrl->flash_window_base);
>  sysbus_connect_irq(SYS_BUS_DEVICE(>fmc), 0,
> qdev_get_gpio_in(DEVICE(>vic), 19));
>  
> @@ -200,7 +198,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
> **errp)
>  return;
>  }
>  sysbus_mmio_map(SYS_BUS_DEVICE(>spi), 0, ASPEED_SOC_SPI_BASE);
> -sysbus_mmio_map(SYS_BUS_DEVICE(>spi), 1, ASPEED_SOC_SPI_FLASH_BASE);
> +sysbus_mmio_map(SYS_BUS_DEVICE(>spi), 1,
> +s->spi.ctrl->flash_window_base);
>  
>  /* SDMC - SDRAM Memory Controller */
>  object_property_set_bool(OBJECT(>sdmc), true, "realized", );
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index d319e04a27f0..84c18299de11 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -127,6 +127,10 @@
>  #define R_SPI_MISC_CTRL   (0x10 / 4)
>  #define R_SPI_TIMINGS (0x14 / 4)
>  
> +#define ASPEED_SOC_SMC_FLASH_BASE   0x1000
> +#define ASPEED_SOC_FMC_FLASH_BASE   0x2000
> +#define ASPEED_SOC_SPI_FLASH_BASE   0x3000
> +
>  /*
>   * Default segments mapping addresses and size for each slave per
>   * controller. These can be changed when board is initialized with the
> @@ -151,11 +155,14 @@ static const AspeedSegments aspeed_segments_spi[] = {
>  
>  static const AspeedSMCController controllers[] = {
>  { "aspeed.smc.smc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
> -  CONF_ENABLE_W0, 5, aspeed_segments_legacy, 0x600 },
> +  CONF_ENABLE_W0, 5, aspeed_segments_legacy,
> +  ASPEED_SOC_SMC_FLASH_BASE, 0x600 },
>  { "aspeed.smc.fmc", R_CONF, R_CE_CTRL, R_CTRL0, R_TIMINGS,
> -  CONF_ENABLE_W0, 5, aspeed_segments_fmc, 0x1000 },
> +  CONF_ENABLE_W0, 5, aspeed_segments_fmc,
> +  ASPEED_SOC_FMC_FLASH_BASE, 0x1000 },
>  { "aspeed.smc.spi", R_SPI_CONF, 0xff, R_SPI_CTRL0, R_SPI_TIMINGS,
> -  SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi, 0x1000 },
> +  SPI_CONF_ENABLE_W0, 1, aspeed_segments_spi,
> +  ASPEED_SOC_SPI_FLASH_BASE, 0x1000 },
>  };
>  
>  static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
> @@ -395,7 +402,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error 
> **errp)
>  
>  memory_region_init_io(>mmio_flash, OBJECT(s),
>    _smc_flash_default_ops, s, name,
> -  s->ctrl->mapping_window_size);
> +  s->ctrl->flash_window_size);
>  sysbus_init_mmio(sbd, >mmio_flash);
>  
>  s->flashes = g_new0(AspeedSMCFlash, s->num_cs);
> diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
> index def3b4507e75..bdfbcc0ffa7d 100644
> --- a/include/hw/ssi/aspeed_smc.h
> +++ b/include/hw/ssi/aspeed_smc.h
> @@ -42,7 +42,8 @@ typedef struct AspeedSMCController {
>  uint8_t conf_enable_w0;
>  uint8_t max_slaves;
>  const AspeedSegments *segments;
> -uint32_t mapping_window_size;
> +hwaddr flash_window_base;
> +uint32_t flash_window_size;
>  } AspeedSMCController;
>  
>  typedef struct AspeedSMCFlash {

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 1/6] aspeed: rename the smc object to fmc

2016-10-04 Thread Andrew Jeffery
On Tue, 2016-09-27 at 13:57 +0200, Cédric Le Goater wrote:
> The Aspeed SoC has three different types of SMC (Static Memory
> Controller) controllers: the SMC (legacy), the FMC (the new one) and
> the SPI for the host PNOR. The FMC and the SPI models are now
> converging on the AST2500 SoC and the SMC, which was still available
> on the AST2400 SoC, was removed.
> 
> The Aspeed SoC does not provide support for the legacy SMC
> controller. So, let's rename the 'smc' object to 'fmc' to clarify its
> nature.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed.c |  2 +-
>  hw/arm/aspeed_soc.c | 18 +-
>  include/hw/arm/aspeed_soc.h |  2 +-
>  3 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 6b18c7f1727c..4bb33cbb5e70 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -128,7 +128,7 @@ static void aspeed_board_init(MachineState *machine,
>  object_property_add_const_link(OBJECT(>soc), "ram", 
> OBJECT(>ram),
> _abort);
>  
> -aspeed_board_init_flashes(>soc.smc, "n25q256a", _abort);
> +aspeed_board_init_flashes(>soc.fmc, "n25q256a", _abort);
>  aspeed_board_init_flashes(>soc.spi, "mx25l25635e", _abort);
>  
>  aspeed_board_binfo.kernel_filename = machine->kernel_filename;
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index c0a310205842..479c0d2039d9 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -100,9 +100,9 @@ static void aspeed_soc_init(Object *obj)
>  object_property_add_alias(obj, "hw-strap2", OBJECT(>scu),
>    "hw-strap2", _abort);
>  
> -object_initialize(>smc, sizeof(s->smc), "aspeed.smc.fmc");
> -object_property_add_child(obj, "smc", OBJECT(>smc), NULL);
> -qdev_set_parent_bus(DEVICE(>smc), sysbus_get_default());
> +object_initialize(>fmc, sizeof(s->fmc), "aspeed.smc.fmc");
> +object_property_add_child(obj, "fmc", OBJECT(>fmc), NULL);
> +qdev_set_parent_bus(DEVICE(>fmc), sysbus_get_default());
>  
>  object_initialize(>spi, sizeof(s->spi), "aspeed.smc.spi");
>  object_property_add_child(obj, "spi", OBJECT(>spi), NULL);
> @@ -178,17 +178,17 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
> **errp)
>  sysbus_connect_irq(SYS_BUS_DEVICE(>i2c), 0,
> qdev_get_gpio_in(DEVICE(>vic), 12));
>  
> -/* SMC */
> -object_property_set_int(OBJECT(>smc), 1, "num-cs", );
> -object_property_set_bool(OBJECT(>smc), true, "realized", _err);
> +/* FMC */
> +object_property_set_int(OBJECT(>fmc), 1, "num-cs", );
> +object_property_set_bool(OBJECT(>fmc), true, "realized", _err);
>  error_propagate(, local_err);
>  if (err) {
>  error_propagate(errp, err);
>  return;
>  }
> -sysbus_mmio_map(SYS_BUS_DEVICE(>smc), 0, ASPEED_SOC_FMC_BASE);
> -sysbus_mmio_map(SYS_BUS_DEVICE(>smc), 1, ASPEED_SOC_FMC_FLASH_BASE);
> -sysbus_connect_irq(SYS_BUS_DEVICE(>smc), 0,
> +sysbus_mmio_map(SYS_BUS_DEVICE(>fmc), 0, ASPEED_SOC_FMC_BASE);
> +sysbus_mmio_map(SYS_BUS_DEVICE(>fmc), 1, ASPEED_SOC_FMC_FLASH_BASE);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>fmc), 0,
> qdev_get_gpio_in(DEVICE(>vic), 19));
>  
>  /* SPI */
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index 932704c380f2..7359e25fce49 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -31,7 +31,7 @@ typedef struct AspeedSoCState {
>  AspeedTimerCtrlState timerctrl;
>  AspeedI2CState i2c;
>  AspeedSCUState scu;
> -AspeedSMCState smc;
> +AspeedSMCState fmc;
>  AspeedSMCState spi;
>  AspeedSDMCState sdmc;
>  } AspeedSoCState;

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v5 14/14] aspeed: allocate RAM after the memory controller has checked the size

2016-09-12 Thread Andrew Jeffery
On Fri, 2016-09-09 at 18:22 +0200, Cédric Le Goater wrote:
> If the RAM size is invalid, the memory controller will use a default
> value.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed.c | 18 +-
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 562bbb253391..6b18c7f1727c 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -108,11 +108,6 @@ static void aspeed_board_init(MachineState *machine,
>  
>  sc = ASPEED_SOC_GET_CLASS(>soc);
>  
> -memory_region_allocate_system_memory(>ram, NULL, "ram", ram_size);
> -memory_region_add_subregion(get_system_memory(), sc->info->sdram_base,
> ->ram);
> -object_property_add_const_link(OBJECT(>soc), "ram", 
> OBJECT(>ram),
> -   _abort);
>  object_property_set_int(OBJECT(>soc), ram_size, "ram-size",
> _abort);
>  object_property_set_int(OBJECT(>soc), cfg->hw_strap1, "hw-strap1",
> @@ -120,6 +115,19 @@ static void aspeed_board_init(MachineState *machine,
>  object_property_set_bool(OBJECT(>soc), true, "realized",
>   _abort);
>  
> +/*
> + * Allocate RAM after the memory controller has checked the size
> + * was valid. If not, a default value is used.
> + */
> +ram_size = object_property_get_int(OBJECT(>soc), "ram-size",
> +   _abort);
> +
> +memory_region_allocate_system_memory(>ram, NULL, "ram", ram_size);
> +memory_region_add_subregion(get_system_memory(), sc->info->sdram_base,
> +>ram);
> +object_property_add_const_link(OBJECT(>soc), "ram", 
> OBJECT(>ram),
> +   _abort);
> +
>  aspeed_board_init_flashes(>soc.smc, "n25q256a", _abort);
>  aspeed_board_init_flashes(>soc.spi, "mx25l25635e", _abort);
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v5 13/14] aspeed: add a ram_size property to the memory controller

2016-09-12 Thread Andrew Jeffery
On Fri, 2016-09-09 at 18:22 +0200, Cédric Le Goater wrote:
> Configure the size of the RAM of the SOC using a property to propagate
> the value down to the memory controller from the board level.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed.c   |  2 ++
>  hw/arm/aspeed_soc.c   |  2 ++
>  hw/misc/aspeed_sdmc.c | 23 +--
>  include/hw/misc/aspeed_sdmc.h |  1 +
>  4 files changed, 18 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 9013d35a674c..562bbb253391 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -113,6 +113,8 @@ static void aspeed_board_init(MachineState *machine,
>  >ram);
>  object_property_add_const_link(OBJECT(>soc), "ram", 
> OBJECT(>ram),
> _abort);
> +object_property_set_int(OBJECT(>soc), ram_size, "ram-size",
> +   _abort);
>  object_property_set_int(OBJECT(>soc), cfg->hw_strap1, "hw-strap1",
>  _abort);
>  object_property_set_bool(OBJECT(>soc), true, "realized",
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 93bc7bb66e4b..c0a310205842 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -113,6 +113,8 @@ static void aspeed_soc_init(Object *obj)
>  qdev_set_parent_bus(DEVICE(>sdmc), sysbus_get_default());
>  qdev_prop_set_uint32(DEVICE(>sdmc), "silicon-rev",
>   sc->info->silicon_rev);
> +object_property_add_alias(obj, "ram-size", OBJECT(>sdmc),
> +  "ram-size", _abort);
>  }
>  
>  static void aspeed_soc_realize(DeviceState *dev, Error **errp)
> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
> index 20bcdb52c4df..8830dc084c38 100644
> --- a/hw/misc/aspeed_sdmc.c
> +++ b/hw/misc/aspeed_sdmc.c
> @@ -140,9 +140,9 @@ static const MemoryRegionOps aspeed_sdmc_ops = {
>  .valid.max_access_size = 4,
>  };
>  
> -static int ast2400_rambits(void)
> +static int ast2400_rambits(AspeedSDMCState *s)
>  {
> -switch (ram_size >> 20) {
> +switch (s->ram_size >> 20) {
>  case 64:
>  return ASPEED_SDMC_DRAM_64MB;
>  case 128:
> @@ -156,14 +156,15 @@ static int ast2400_rambits(void)
>  }
>  
>  /* use a common default */
> -error_report("warning: Invalid RAM size 0x" RAM_ADDR_FMT
> - ". Using default 256M", ram_size);
> +error_report("warning: Invalid RAM size 0x%" PRIx64
> + ". Using default 256M", s->ram_size);
> +s->ram_size = 256 << 20;
>  return ASPEED_SDMC_DRAM_256MB;
>  }
>  
> -static int ast2500_rambits(void)
> +static int ast2500_rambits(AspeedSDMCState *s)
>  {
> -switch (ram_size >> 20) {
> +switch (s->ram_size >> 20) {
>  case 128:
>  return ASPEED_SDMC_AST2500_128MB;
>  case 256:
> @@ -177,8 +178,9 @@ static int ast2500_rambits(void)
>  }
>  
>  /* use a common default */
> -error_report("warning: Invalid RAM size 0x" RAM_ADDR_FMT
> - ". Using default 512M", ram_size);
> +error_report("warning: Invalid RAM size 0x%" PRIx64
> + ". Using default 512M", s->ram_size);
> +s->ram_size = 512 << 20;
>  return ASPEED_SDMC_AST2500_512MB;
>  }
>  
> @@ -222,11 +224,11 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error 
> **errp)
>  
>  switch (s->silicon_rev) {
>  case AST2400_A0_SILICON_REV:
> -s->ram_bits = ast2400_rambits();
> +s->ram_bits = ast2400_rambits(s);
>  break;
>  case AST2500_A0_SILICON_REV:
>  case AST2500_A1_SILICON_REV:
> -s->ram_bits = ast2500_rambits();
> +s->ram_bits = ast2500_rambits(s);
>  break;
>  default:
>  g_assert_not_reached();
> @@ -249,6 +251,7 @@ static const VMStateDescription vmstate_aspeed_sdmc = {
>  
>  static Property aspeed_sdmc_properties[] = {
>  DEFINE_PROP_UINT32("silicon-rev", AspeedSDMCState, silicon_rev, 0),
> +DEFINE_PROP_UINT64("ram-size", AspeedSDMCState, ram_size, 0),
>  DEFINE_PROP_END_OF_LIST(),
>  };
>  
> diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
> index df7dce0edddf..551c8afdf4be 100644
> --- a/include/hw/misc/aspeed_sdmc.h
> +++ b/include/hw/misc/aspeed_sdmc.h
> @@ -26,6 +26,7 @@ typedef struct AspeedSDMCState {
>  uint32_t regs[ASPEED_SDMC_NR_REGS];
>  uint32_t silicon_rev;
>  uint32_t ram_bits;
> +uint64_t ram_size;
>  
>  } AspeedSDMCState;
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v5 12/14] aspeed: use error_report instead of LOG_GUEST_ERROR

2016-09-12 Thread Andrew Jeffery
On Fri, 2016-09-09 at 18:22 +0200, Cédric Le Goater wrote:
> Also change the default value used in case of an error. The minimum
> size is a bit severe, so let's just use an average RAM size.

I'm not sure we should be switching the default value in this patch,
but I'm not sure it's worth any effort to split it out either...

Otherwise, both the changes seem sensible enough.

Andrew

> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/misc/aspeed_sdmc.c | 17 +
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
> index 1d2825237728..20bcdb52c4df 100644
> --- a/hw/misc/aspeed_sdmc.c
> +++ b/hw/misc/aspeed_sdmc.c
> @@ -9,6 +9,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "qemu/log.h"
> +#include "qemu/error-report.h"
>  #include "hw/misc/aspeed_sdmc.h"
>  #include "hw/misc/aspeed_scu.h"
>  #include "hw/qdev-properties.h"
> @@ -151,13 +152,13 @@ static int ast2400_rambits(void)
>  case 512:
>  return ASPEED_SDMC_DRAM_512MB;
>  default:
> -qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid RAM size: 0x"
> -  RAM_ADDR_FMT "\n", __func__, ram_size);
>  break;
>  }
>  
> -/* set a minimum default */
> -return ASPEED_SDMC_DRAM_64MB;
> +/* use a common default */
> +error_report("warning: Invalid RAM size 0x" RAM_ADDR_FMT
> + ". Using default 256M", ram_size);
> +return ASPEED_SDMC_DRAM_256MB;
>  }
>  
>  static int ast2500_rambits(void)
> @@ -172,13 +173,13 @@ static int ast2500_rambits(void)
>  case 1024:
>  return ASPEED_SDMC_AST2500_1024MB;
>  default:
> -qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid RAM size: 0x"
> -  RAM_ADDR_FMT "\n", __func__, ram_size);
>  break;
>  }
>  
> -/* set a minimum default */
> -return ASPEED_SDMC_AST2500_128MB;
> +/* use a common default */
> +error_report("warning: Invalid RAM size 0x" RAM_ADDR_FMT
> + ". Using default 512M", ram_size);
> +return ASPEED_SDMC_AST2500_512MB;
>  }
>  
>  static void aspeed_sdmc_reset(DeviceState *dev)

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v5 11/14] aspeed: calculate the RAM size bits at realize time

2016-09-12 Thread Andrew Jeffery
On Fri, 2016-09-09 at 18:22 +0200, Cédric Le Goater wrote:
> There is no need to do this at each reset as the RAM size will not
> change.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/misc/aspeed_sdmc.c | 16 ++--
>  include/hw/misc/aspeed_sdmc.h |  1 +
>  2 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
> index 244e5c0dc5ef..1d2825237728 100644
> --- a/hw/misc/aspeed_sdmc.c
> +++ b/hw/misc/aspeed_sdmc.c
> @@ -192,7 +192,7 @@ static void aspeed_sdmc_reset(DeviceState *dev)
>  case AST2400_A0_SILICON_REV:
>  s->regs[R_CONF] |=
>  ASPEED_SDMC_VGA_COMPAT |
> -ASPEED_SDMC_DRAM_SIZE(ast2400_rambits());
> +ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
>  break;
>  
>  case AST2500_A0_SILICON_REV:
> @@ -200,7 +200,7 @@ static void aspeed_sdmc_reset(DeviceState *dev)
>  s->regs[R_CONF] |=
>  ASPEED_SDMC_HW_VERSION(1) |
>  ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
> -ASPEED_SDMC_DRAM_SIZE(ast2500_rambits());
> +ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
>  break;
>  
>  default:
> @@ -219,6 +219,18 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error 
> **errp)
>  return;
>  }
>  
> +switch (s->silicon_rev) {
> +case AST2400_A0_SILICON_REV:
> +s->ram_bits = ast2400_rambits();
> +break;
> +case AST2500_A0_SILICON_REV:
> +case AST2500_A1_SILICON_REV:
> +s->ram_bits = ast2500_rambits();
> +break;
> +default:
> +g_assert_not_reached();
> +}
> +
>  memory_region_init_io(>iomem, OBJECT(s), _sdmc_ops, s,
>    TYPE_ASPEED_SDMC, 0x1000);
>  sysbus_init_mmio(sbd, >iomem);
> diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
> index 7e081f6d2b86..df7dce0edddf 100644
> --- a/include/hw/misc/aspeed_sdmc.h
> +++ b/include/hw/misc/aspeed_sdmc.h
> @@ -25,6 +25,7 @@ typedef struct AspeedSDMCState {
>  
>  uint32_t regs[ASPEED_SDMC_NR_REGS];
>  uint32_t silicon_rev;
> +uint32_t ram_bits;
>  
>  } AspeedSDMCState;
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v3 10/10] palmetto-bmc: remove extra no_sdcard assignement

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index e71500c64bd3..6d7b70df70da 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -145,7 +145,6 @@ static void palmetto_bmc_class_init(ObjectClass *oc, void 
> *data)
>  mc->no_sdcard = 1;
>  mc->no_floppy = 1;
>  mc->no_cdrom = 1;
> -mc->no_sdcard = 1;
>  mc->no_parallel = 1;
>  }
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v3 09/10] arm: add support for an ast2500 evaluation board

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> The ast2500 eval board has a hardware strapping register value of
> 0xF100C2E6 which we use for a definition of AST2500_EVB_HW_STRAP1
> below.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
> 
>  Changes since v2:
> 
>  - removed silicon-rev and cpu-model. This is now in the SoC.
> 
>  Changes since v1:
> 
>  - changed AST2500_EDK to AST2500_EVB
>  - fixed white space issues
>  - added AST2500_HW_STRAP1 
> 
>  hw/arm/aspeed.c | 39 ++-
>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 80907b4244ea..e71500c64bd3 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -36,7 +36,8 @@ typedef struct AspeedBoardConfig {
>  } AspeedBoardConfig;
>  
>  enum {
> -PALMETTO_BMC
> +PALMETTO_BMC,
> +AST2500_EVB
>  };
>  
>  #define PALMETTO_BMC_HW_STRAP1 (\
> @@ -52,8 +53,19 @@ enum {
>  SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) |   \
>  SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT))
>  
> +#define AST2500_EVB_HW_STRAP1 ((\
> +AST2500_HW_STRAP1_DEFAULTS |\
> +SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
> +SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE |\
> +SCU_AST2500_HW_STRAP_UART_DEBUG |   \
> +SCU_AST2500_HW_STRAP_DDR4_ENABLE |  \
> +SCU_HW_STRAP_MAC1_RGMII |   \
> +SCU_HW_STRAP_MAC0_RGMII) &  \
> +~SCU_HW_STRAP_2ND_BOOT_WDT)
> +
>  static const AspeedBoardConfig aspeed_boards[] = {
>  [PALMETTO_BMC] = { "ast2400-a0", PALMETTO_BMC_HW_STRAP1 },
> +[AST2500_EVB]  = { "ast2500-a1", AST2500_EVB_HW_STRAP1 },
>  };
>  
>  static void aspeed_board_init_flashes(AspeedSMCState *s, const char 
> *flashtype,
> @@ -143,9 +155,34 @@ static const TypeInfo palmetto_bmc_type = {
>  .class_init = palmetto_bmc_class_init,
>  };
>  
> +static void ast2500_evb_init(MachineState *machine)
> +{
> +aspeed_board_init(machine, _boards[AST2500_EVB]);
> +}
> +
> +static void ast2500_evb_class_init(ObjectClass *oc, void *data)
> +{
> +MachineClass *mc = MACHINE_CLASS(oc);
> +
> +mc->desc = "Aspeed AST2500 EVB (ARM1176)";
> +mc->init = ast2500_evb_init;
> +mc->max_cpus = 1;
> +mc->no_sdcard = 1;
> +mc->no_floppy = 1;
> +mc->no_cdrom = 1;
> +mc->no_parallel = 1;
> +}
> +
> +static const TypeInfo ast2500_evb_type = {
> +.name = MACHINE_TYPE_NAME("ast2500-evb"),
> +.parent = TYPE_MACHINE,
> +.class_init = ast2500_evb_class_init,
> +};
> +
>  static void aspeed_machine_init(void)
>  {
>  type_register_static(_bmc_type);
> +type_register_static(_evb_type);
>  }
>  
>  type_init(aspeed_machine_init)

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v3 08/10] aspeed: add a AST2500 SoC and support to the SCU and SDMC controllers controllers

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> Based on previous work done by Andrew Jeffery <and...@aj.id.au>.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
> 
>  Changes since v2:
> 
>  - more precise definitions of the hw-strap1 register
> 
>  hw/arm/aspeed_soc.c  |  2 ++
>  hw/misc/aspeed_scu.c | 45 +-
>  hw/misc/aspeed_sdmc.c|  1 +
>  include/hw/misc/aspeed_scu.h | 77 
> +++-
>  4 files changed, 123 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index ec6ec3546908..2408dfe70c51 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -38,10 +38,12 @@ static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
>  static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
>  
>  #define AST2400_SDRAM_BASE   0x4000
> +#define AST2500_SDRAM_BASE   0x8000
>  
>  static const AspeedSoCInfo aspeed_socs[] = {
>  { "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE },
>  { "ast2400","arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE },
> +{ "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE },
>  };
>  
>  /*
> diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> index c7e2c8263f55..6dd7e1085420 100644
> --- a/hw/misc/aspeed_scu.c
> +++ b/hw/misc/aspeed_scu.c
> @@ -120,6 +120,41 @@ static const uint32_t 
> ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
>   [BMC_DEV_ID]  = 0x2402U
>  };
>  
> +/* SCU70 bit 23: 0 24Mhz. bit 11:9: 0b001 AXI:ABH ratio 2:1 */
> +/* AST2500 revision A1 */
> +
> +static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
> + [SYS_RST_CTRL]= 0xFFCFFEDCU,
> + [CLK_SEL] = 0xF3F4U,
> + [CLK_STOP_CTRL]   = 0x19FC3E8BU,
> + [D2PLL_PARAM] = 0x00026108U,
> + [MPLL_PARAM]  = 0x00030291U,
> + [HPLL_PARAM]  = 0x93000400U,
> + [MISC_CTRL1]  = 0x0010U,
> + [PCI_CTRL1]   = 0x20001A03U,
> + [PCI_CTRL2]   = 0x20001A03U,
> + [PCI_CTRL3]   = 0x0430U,
> + [SYS_RST_STATUS]  = 0x0001U,
> + [SOC_SCRATCH1]= 0x00C0U, /* SoC completed DRAM init */
> + [MISC_CTRL2]  = 0x0023U,
> + [RNG_CTRL]= 0x000EU,
> + [PINMUX_CTRL2]= 0xF000U,
> + [PINMUX_CTRL3]= 0x0300U,
> + [PINMUX_CTRL4]= 0xU,
> + [PINMUX_CTRL5]= 0xA000U,
> + [WDT_RST_CTRL]= 0x0233U,
> + [PINMUX_CTRL8]= 0xU,
> + [PINMUX_CTRL9]= 0x000FU,
> + [FREE_CNTR4]  = 0x00FFU,
> + [FREE_CNTR4_EXT]  = 0x00FFU,
> + [CPU2_BASE_SEG1]  = 0x8000U,
> + [CPU2_BASE_SEG4]  = 0x1E60U,
> + [CPU2_BASE_SEG5]  = 0xC000U,
> + [UART_HPLL_CLK]   = 0x1903U,
> + [PCIE_CTRL]   = 0x007BU,
> + [BMC_DEV_ID]  = 0x2402U
> +};
> +
>  static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
>  {
>  AspeedSCUState *s = ASPEED_SCU(opaque);
> @@ -198,6 +233,10 @@ static void aspeed_scu_reset(DeviceState *dev)
>  case AST2400_A0_SILICON_REV:
>  reset = ast2400_a0_resets;
>  break;
> +case AST2500_A0_SILICON_REV:
> +case AST2500_A1_SILICON_REV:
> +reset = ast2500_a1_resets;
> +break;
>  default:
>  g_assert_not_reached();
>  }
> @@ -208,7 +247,11 @@ static void aspeed_scu_reset(DeviceState *dev)
>  s->regs[HW_STRAP2] = s->hw_strap2;
>  }
>  
> -static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, };
> +static uint32_t aspeed_silicon_revs[] = {
> +AST2400_A0_SILICON_REV,
> +AST2500_A0_SILICON_REV,
> +AST2500_A1_SILICON_REV
> +};
>  
>  bool is_supported_silicon_rev(uint32_t silicon_rev)
>  {
> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
> index 6cc0301a6331..621d166890fa 100644
> --- a/hw/misc/aspeed_sdmc.c
> +++ b/hw/misc/aspeed_sdmc.c
> @@ -196,6 +196,7 @@ static void aspeed_sdmc_reset(DeviceState *dev)
>  break;
>  
>  case AST2500_A0_SILICON_REV:
> +case AST2500_A1_SILICON_REV:
>  s->regs[R_CONF] |=
>  ASPEED_SDMC_HW_VERSION(1) |
>  ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
> diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
> index 0761f0880c69..20d7559d3395 100644
> --- a/include/hw/misc/aspeed_scu.h
> +++ b/include/hw/misc/aspeed_scu.h
&g

Re: [Qemu-devel] [PATCH v3 07/10] hw/misc: use macros to define hw-strap1 register on the AST2400 Aspeed SoC

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> This gives some explanation behind the magic number 0x120CE416.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
> 
>  Changes since v2:
> 
>  - more precise definitions of the hw-strap1 register
>  - moved hw-strap1 to the board level.
> 
>  hw/arm/aspeed.c  |  15 +-
>  include/hw/misc/aspeed_scu.h | 118 
> +++
>  2 files changed, 132 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 4226b8dcd95c..80907b4244ea 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -39,8 +39,21 @@ enum {
>  PALMETTO_BMC
>  };
>  
> +#define PALMETTO_BMC_HW_STRAP1 (\
> +SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) |   \
> +SCU_AST2400_HW_STRAP_DRAM_CONFIG(2 /* DDR3 with CL=6, CWL=5 */) | \
> +SCU_AST2400_HW_STRAP_ACPI_DIS | \
> +SCU_AST2400_HW_STRAP_SET_CLK_SOURCE(AST2400_CLK_48M_IN) |   \
> +SCU_HW_STRAP_VGA_CLASS_CODE |   \
> +SCU_HW_STRAP_LPC_RESET_PIN |\
> +SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_M_S_EN) |\
> +SCU_AST2400_HW_STRAP_SET_CPU_AHB_RATIO(AST2400_CPU_AHB_RATIO_2_1) | \
> +SCU_HW_STRAP_SPI_WIDTH |\
> +SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) |   \
> +SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT))
> +
>  static const AspeedBoardConfig aspeed_boards[] = {
> -[PALMETTO_BMC] = { "ast2400-a0", 0x120CE416 },
> +[PALMETTO_BMC] = { "ast2400-a0", PALMETTO_BMC_HW_STRAP1 },
>  };
>  
>  static void aspeed_board_init_flashes(AspeedSMCState *s, const char 
> *flashtype,
> diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
> index fdfd982288f2..0761f0880c69 100644
> --- a/include/hw/misc/aspeed_scu.h
> +++ b/include/hw/misc/aspeed_scu.h
> @@ -36,4 +36,122 @@ typedef struct AspeedSCUState {
>  
>  extern bool is_supported_silicon_rev(uint32_t silicon_rev);
>  
> +/*
> + * Extracted from Aspeed SDK v00.03.21. Fixes and extra definitions
> + * were added.
> + *
> + * Original header file :
> + *arch/arm/mach-aspeed/include/mach/regs-scu.h
> + *
> + *Copyright (C) 2012-2020  ASPEED Technology Inc.
> + *
> + *This program is free software; you can redistribute it and/or modify
> + *it under the terms of the GNU General Public License version 2 as
> + *published by the Free Software Foundation.
> + *
> + *  History  :
> + *   1. 2012/12/29 Ryan Chen Create
> + */
> +
> +/* Hardware Strapping Register definition (for Aspeed AST2400 SOC)
> + *
> + * 31:29  Software defined strapping registers
> + * 28:27  DRAM size setting (for VGA driver use)
> + * 26:24  DRAM configuration setting
> + * 23 Enable 25 MHz reference clock input
> + * 22 Enable GPIOE pass-through mode
> + * 21 Enable GPIOD pass-through mode
> + * 20 Disable LPC to decode SuperIO 0x2E/0x4E address
> + * 19 Disable ACPI function
> + * 23,18  Clock source selection
> + * 17 Enable BMC 2nd boot watchdog timer
> + * 16 SuperIO configuration address selection
> + * 15 VGA Class Code selection
> + * 14 Enable LPC dedicated reset pin function
> + * 13:12  SPI mode selection
> + * 11:10  CPU/AHB clock frequency ratio selection
> + * 9:8H-PLL default clock frequency selection
> + * 7  Define MAC#2 interface
> + * 6  Define MAC#1 interface
> + * 5  Enable VGA BIOS ROM
> + * 4  Boot flash memory extended option
> + * 3:2VGA memory size selection
> + * 1:0BMC CPU boot code selection
> + */
> +#define SCU_AST2400_HW_STRAP_SW_DEFINE(x)  (x << 29)
> +#define SCU_AST2400_HW_STRAP_SW_DEFINE_MASK(0x7 << 29)
> +
> +#define SCU_AST2400_HW_STRAP_DRAM_SIZE(x)  (x << 27)
> +#define SCU_AST2400_HW_STRAP_DRAM_SIZE_MASK(0x3 << 27)
> +#define DRAM_SIZE_64MB 0
> +#define DRAM_SIZE_128MB1
> +#define DRAM_SIZE_256MB2
> +#define DRAM_SIZE_512MB3
> +
> +#define SCU_AST2400_HW_STRAP_DRAM_CONFIG(x)(x << 24)
> +#define SCU_AST2400_HW_STRAP_DRAM_CONFIG_MASK  (0x7 << 24)
> +
> +#define SCU_HW_STRAP_GPIOE_PT_EN   (0x1 << 22)
> +#define SCU_HW_STRAP_GPIOD_PT_EN

Re: [Qemu-devel] [PATCH v3 06/10] palmetto-bmc: add board specific configuration

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> aspeed_board_init() now uses a board identifier to customize some values
> specific to the board.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
> 
>  Changes since v2:
> 
>  - removed silicon-rev and cpu-model. This is now in the SoC.
> 
>  Changes since v1:
> 
>  - changed aspeed_init() prototype to use a 'const AspeedBoardConfig *'
>  - fixed white space issues
> 
>  hw/arm/aspeed.c | 22 ++
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index ad0a062b5624..4226b8dcd95c 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -30,6 +30,19 @@ typedef struct AspeedBoardState {
>  MemoryRegion ram;
>  } AspeedBoardState;
>  
> +typedef struct AspeedBoardConfig {
> +const char *soc_name;
> +uint32_t hw_strap1;
> +} AspeedBoardConfig;
> +
> +enum {
> +PALMETTO_BMC
> +};
> +
> +static const AspeedBoardConfig aspeed_boards[] = {
> +[PALMETTO_BMC] = { "ast2400-a0", 0x120CE416 },
> +};
> +
>  static void aspeed_board_init_flashes(AspeedSMCState *s, const char 
> *flashtype,
>    Error **errp)
>  {
> @@ -56,13 +69,14 @@ static void aspeed_board_init_flashes(AspeedSMCState *s, 
> const char *flashtype,
>  }
>  }
>  
> -static void aspeed_board_init(MachineState *machine)
> +static void aspeed_board_init(MachineState *machine,
> +  const AspeedBoardConfig *cfg)
>  {
>  AspeedBoardState *bmc;
>  AspeedSoCClass *sc;
>  
>  bmc = g_new0(AspeedBoardState, 1);
> -object_initialize(>soc, (sizeof(bmc->soc)), "ast2400-a0");
> +object_initialize(>soc, (sizeof(bmc->soc)), cfg->soc_name);
>  object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
>    _abort);
>  
> @@ -73,7 +87,7 @@ static void aspeed_board_init(MachineState *machine)
>  >ram);
>  object_property_add_const_link(OBJECT(>soc), "ram", 
> OBJECT(>ram),
> _abort);
> -object_property_set_int(OBJECT(>soc), 0x120CE416, "hw-strap1",
> +object_property_set_int(OBJECT(>soc), cfg->hw_strap1, "hw-strap1",
>  _abort);
>  object_property_set_bool(OBJECT(>soc), true, "realized",
>   _abort);
> @@ -93,7 +107,7 @@ static void aspeed_board_init(MachineState *machine)
>  
>  static void palmetto_bmc_init(MachineState *machine)
>  {
> -aspeed_board_init(machine);
> +aspeed_board_init(machine, _boards[PALMETTO_BMC]);
>  }
>  
>  static void palmetto_bmc_class_init(ObjectClass *oc, void *data)

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v3 05/10] palmetto-bmc: replace palmetto_bmc with aspeed

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> This is mostly a name replacement to prepare ground for other SoCs
> specificities. It also adds a TypeInfo struct for the palmetto-bmc
> board with a custom initialization for the same reason.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed.c | 56 +---
>  1 file changed, 37 insertions(+), 19 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 531c266d9449..ad0a062b5624 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -21,16 +21,16 @@
>  #include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  
> -static struct arm_boot_info palmetto_bmc_binfo = {
> +static struct arm_boot_info aspeed_board_binfo = {
>  .nb_cpus = 1,
>  };
>  
> -typedef struct PalmettoBMCState {
> +typedef struct AspeedBoardState {
>  AspeedSoCState soc;
>  MemoryRegion ram;
> -} PalmettoBMCState;
> +} AspeedBoardState;
>  
> -static void palmetto_bmc_init_flashes(AspeedSMCState *s, const char 
> *flashtype,
> +static void aspeed_board_init_flashes(AspeedSMCState *s, const char 
> *flashtype,
>    Error **errp)
>  {
>  int i ;
> @@ -56,12 +56,12 @@ static void palmetto_bmc_init_flashes(AspeedSMCState *s, 
> const char *flashtype,
>  }
>  }
>  
> -static void palmetto_bmc_init(MachineState *machine)
> +static void aspeed_board_init(MachineState *machine)
>  {
> -PalmettoBMCState *bmc;
> +AspeedBoardState *bmc;
>  AspeedSoCClass *sc;
>  
> -bmc = g_new0(PalmettoBMCState, 1);
> +bmc = g_new0(AspeedBoardState, 1);
>  object_initialize(>soc, (sizeof(bmc->soc)), "ast2400-a0");
>  object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
>    _abort);
> @@ -78,22 +78,29 @@ static void palmetto_bmc_init(MachineState *machine)
>  object_property_set_bool(OBJECT(>soc), true, "realized",
>   _abort);
>  
> -palmetto_bmc_init_flashes(>soc.smc, "n25q256a", _abort);
> -palmetto_bmc_init_flashes(>soc.spi, "mx25l25635e", _abort);
> +aspeed_board_init_flashes(>soc.smc, "n25q256a", _abort);
> +aspeed_board_init_flashes(>soc.spi, "mx25l25635e", _abort);
> +
> +aspeed_board_binfo.kernel_filename = machine->kernel_filename;
> +aspeed_board_binfo.initrd_filename = machine->initrd_filename;
> +aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline;
> +aspeed_board_binfo.ram_size = ram_size;
> +aspeed_board_binfo.board_id = sc->info->silicon_rev;
> +aspeed_board_binfo.loader_start = sc->info->sdram_base;
>  
> -palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
> -palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
> -palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
> -palmetto_bmc_binfo.ram_size = ram_size;
> -palmetto_bmc_binfo.board_id = sc->info->silicon_rev;
> -palmetto_bmc_binfo.loader_start = sc->info->sdram_base;
> +arm_load_kernel(ARM_CPU(first_cpu), _board_binfo);
> +}
>  
> -arm_load_kernel(ARM_CPU(first_cpu), _bmc_binfo);
> +static void palmetto_bmc_init(MachineState *machine)
> +{
> +aspeed_board_init(machine);
>  }
>  
> -static void palmetto_bmc_machine_init(MachineClass *mc)
> +static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
>  {
> -mc->desc = "OpenPOWER Palmetto BMC";
> +MachineClass *mc = MACHINE_CLASS(oc);
> +
> +mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
>  mc->init = palmetto_bmc_init;
>  mc->max_cpus = 1;
>  mc->no_sdcard = 1;
> @@ -103,4 +110,15 @@ static void palmetto_bmc_machine_init(MachineClass *mc)
>  mc->no_parallel = 1;
>  }
>  
> -DEFINE_MACHINE("palmetto-bmc", palmetto_bmc_machine_init);
> +static const TypeInfo palmetto_bmc_type = {
> +.name = MACHINE_TYPE_NAME("palmetto-bmc"),
> +.parent = TYPE_MACHINE,
> +.class_init = palmetto_bmc_class_init,
> +};
> +
> +static void aspeed_machine_init(void)
> +{
> +type_register_static(_bmc_type);
> +}
> +
> +type_init(aspeed_machine_init)

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v3 04/10] palmetto-bmc: rename the Aspeed board file to aspeed.c

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> We plan to add more Aspeed boards to this file. There are no changes
> in the code.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/Makefile.objs  |   2 +-
>  hw/arm/aspeed.c   | 106 
> ++
>  hw/arm/palmetto-bmc.c | 106 
> --
>  3 files changed, 107 insertions(+), 107 deletions(-)
>  create mode 100644 hw/arm/aspeed.c
>  delete mode 100644 hw/arm/palmetto-bmc.c
> 
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 7901294630b1..4c5c4ee76c12 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -17,4 +17,4 @@ obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
>  obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
>  obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
>  obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
> -obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o palmetto-bmc.o
> +obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> new file mode 100644
> index ..531c266d9449
> --- /dev/null
> +++ b/hw/arm/aspeed.c
> @@ -0,0 +1,106 @@
> +/*
> + * OpenPOWER Palmetto BMC
> + *
> + * Andrew Jeffery <and...@aj.id.au>
> + *
> + * Copyright 2016 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 "qapi/error.h"
> +#include "qemu-common.h"
> +#include "cpu.h"
> +#include "exec/address-spaces.h"
> +#include "hw/arm/arm.h"
> +#include "hw/arm/aspeed_soc.h"
> +#include "hw/boards.h"
> +#include "qemu/log.h"
> +#include "sysemu/block-backend.h"
> +#include "sysemu/blockdev.h"
> +
> +static struct arm_boot_info palmetto_bmc_binfo = {
> +.nb_cpus = 1,
> +};
> +
> +typedef struct PalmettoBMCState {
> +AspeedSoCState soc;
> +MemoryRegion ram;
> +} PalmettoBMCState;
> +
> +static void palmetto_bmc_init_flashes(AspeedSMCState *s, const char 
> *flashtype,
> +  Error **errp)
> +{
> +int i ;
> +
> +for (i = 0; i < s->num_cs; ++i) {
> +AspeedSMCFlash *fl = >flashes[i];
> +DriveInfo *dinfo = drive_get_next(IF_MTD);
> +qemu_irq cs_line;
> +
> +/*
> + * FIXME: check that we are not using a flash module exceeding
> + * the controller segment size
> + */
> +fl->flash = ssi_create_slave_no_init(s->spi, flashtype);
> +if (dinfo) {
> +qdev_prop_set_drive(fl->flash, "drive", 
> blk_by_legacy_dinfo(dinfo),
> +errp);
> +}
> +qdev_init_nofail(fl->flash);
> +
> +cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
> +sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
> +}
> +}
> +
> +static void palmetto_bmc_init(MachineState *machine)
> +{
> +PalmettoBMCState *bmc;
> +AspeedSoCClass *sc;
> +
> +bmc = g_new0(PalmettoBMCState, 1);
> +object_initialize(>soc, (sizeof(bmc->soc)), "ast2400-a0");
> +object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
> +  _abort);
> +
> +sc = ASPEED_SOC_GET_CLASS(>soc);
> +
> +memory_region_allocate_system_memory(>ram, NULL, "ram", ram_size);
> +memory_region_add_subregion(get_system_memory(), sc->info->sdram_base,
> +>ram);
> +object_property_add_const_link(OBJECT(>soc), "ram", 
> OBJECT(>ram),
> +   _abort);
> +object_property_set_int(OBJECT(>soc), 0x120CE416, "hw-strap1",
> +_abort);
> +object_property_set_bool(OBJECT(>soc), true, "realized",
> + _abort);
> +
> +palmetto_bmc_init_flashes(>soc.smc, "n25q256a", _abort);
> +palmetto_bmc_init_flashes(>soc.spi, "mx25l25635e", _abort);
> +
> +palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
> +palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
> +palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
> +palmetto_bmc_binfo.ram_size = ram_size;
> +palmetto_bmc_binfo.board_id = sc->info->silicon

Re: [Qemu-devel] [PATCH v3 03/10] aspeed-soc: provide a framework to add new SoCs

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> Let's define an object class for each Aspeed SoC we support. A
> AspeedSoCInfo struct gathers the SoC specifications which can later
> be
> used by an instance of the class or by a board using the SoC.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed_soc.c | 27 ---
>  hw/arm/palmetto-bmc.c   | 12 
>  include/hw/arm/aspeed_soc.h | 17 -
>  3 files changed, 48 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 1bec478fef68..ec6ec3546908 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -37,6 +37,13 @@
>  static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
>  static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
>  
> +#define AST2400_SDRAM_BASE   0x4000
> +
> +static const AspeedSoCInfo aspeed_socs[] = {
> +{ "ast2400-a0", "arm926", AST2400_A0_SILICON_REV,
> AST2400_SDRAM_BASE },
> +{ "ast2400","arm926", AST2400_A0_SILICON_REV,
> AST2400_SDRAM_BASE },
> +};
> +
>  /*
>   * IO handlers: simply catch any reads/writes to IO addresses that
> aren't
>   * handled by a device mapping.
> @@ -65,8 +72,9 @@ static const MemoryRegionOps aspeed_soc_io_ops = {
>  static void aspeed_soc_init(Object *obj)
>  {
>  AspeedSoCState *s = ASPEED_SOC(obj);
> +AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
>  
> -s->cpu = cpu_arm_init("arm926");
> +s->cpu = cpu_arm_init(sc->info->cpu_model);
>  
>  object_initialize(>vic, sizeof(s->vic), TYPE_ASPEED_VIC);
>  object_property_add_child(obj, "vic", OBJECT(>vic), NULL);
> @@ -84,7 +92,7 @@ static void aspeed_soc_init(Object *obj)
>  object_property_add_child(obj, "scu", OBJECT(>scu), NULL);
>  qdev_set_parent_bus(DEVICE(>scu), sysbus_get_default());
>  qdev_prop_set_uint32(DEVICE(>scu), "silicon-rev",
> - AST2400_A0_SILICON_REV);
> + sc->info->silicon_rev);
>  object_property_add_alias(obj, "hw-strap1", OBJECT(>scu),
>    "hw-strap1", _abort);
>  object_property_add_alias(obj, "hw-strap2", OBJECT(>scu),
> @@ -102,7 +110,7 @@ static void aspeed_soc_init(Object *obj)
>  object_property_add_child(obj, "sdmc", OBJECT(>sdmc), NULL);
>  qdev_set_parent_bus(DEVICE(>sdmc), sysbus_get_default());
>  qdev_prop_set_uint32(DEVICE(>sdmc), "silicon-rev",
> - AST2400_A0_SILICON_REV);
> + sc->info->silicon_rev);
>  }
>  
>  static void aspeed_soc_realize(DeviceState *dev, Error **errp)
> @@ -202,7 +210,9 @@ static void aspeed_soc_realize(DeviceState *dev,
> Error **errp)
>  static void aspeed_soc_class_init(ObjectClass *oc, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(oc);
> +AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
>  
> +sc->info = (AspeedSoCInfo *) data;
>  dc->realize = aspeed_soc_realize;
>  
>  /*
> @@ -222,7 +232,18 @@ static const TypeInfo aspeed_soc_type_info = {
>  
>  static void aspeed_soc_register_types(void)
>  {
> +int i;
> +
>  type_register_static(_soc_type_info);
> +for (i = 0; i < ARRAY_SIZE(aspeed_socs); ++i) {
> +TypeInfo ti = {
> +.name   = aspeed_socs[i].name,
> +.parent = TYPE_ASPEED_SOC,
> +.class_init = aspeed_soc_class_init,
> +.class_data = (void *) _socs[i],
> +};
> +type_register();
> +}
>  }
>  
>  type_init(aspeed_soc_register_types)
> diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
> index 4d11905cfb18..531c266d9449 100644
> --- a/hw/arm/palmetto-bmc.c
> +++ b/hw/arm/palmetto-bmc.c
> @@ -22,8 +22,6 @@
>  #include "sysemu/blockdev.h"
>  
>  static struct arm_boot_info palmetto_bmc_binfo = {
> -.loader_start = AST2400_SDRAM_BASE,
> -.board_id = 0,
>  .nb_cpus = 1,
>  };
>  
> @@ -61,14 +59,17 @@ static void
> palmetto_bmc_init_flashes(AspeedSMCState *s, const char *flashtype,
>  static void palmetto_bmc_init(MachineState *machine)
>  {
>  PalmettoBMCState *bmc;
> +AspeedSoCClass *sc;
>  
>  bmc = g_new0(PalmettoBMCState, 1);
> -object_initialize(>soc, (sizeof(bmc->soc)),
> TYPE_ASPEED_SOC);
> +object_initialize(>soc, (sizeof(bmc->soc)), "ast2400-a0");
&

Re: [Qemu-devel] [PATCH v3 02/10] ast2400: replace ast2400 with aspeed_soc

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> This is a name replacement to prepare ground for other SoCs.
> 
> Let's also remove the AST2400_SMC_BASE definition from the address
> space mappings, as it is not used. This controller was removed from
> the Aspeed SoC AST2500, so this provides us a better common base for
> the address space mapping on both SoCs.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/aspeed_soc.c | 95 ++-
> --
>  hw/arm/palmetto-bmc.c   |  4 +-
>  include/hw/arm/aspeed_soc.h | 16 
>  3 files changed, 57 insertions(+), 58 deletions(-)
> 
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index b272f4e48cfc..1bec478fef68 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -1,5 +1,5 @@
>  /*
> - * AST2400 SoC
> + * ASPEED SoC family
>   *
>   * Andrew Jeffery <and...@aj.id.au>
>   * Jeremy Kerr <j...@ozlabs.org>
> @@ -20,20 +20,19 @@
>  #include "qemu/log.h"
>  #include "hw/i2c/aspeed_i2c.h"
>  
> -#define AST2400_UART_5_BASE  0x00184000
> -#define AST2400_IOMEM_SIZE   0x0020
> -#define AST2400_IOMEM_BASE   0x1E60
> -#define AST2400_SMC_BASE AST2400_IOMEM_BASE /* Legacy SMC */
> -#define AST2400_FMC_BASE 0X1E62
> -#define AST2400_SPI_BASE 0X1E63
> -#define AST2400_VIC_BASE 0x1E6C
> -#define AST2400_SDMC_BASE0x1E6E
> -#define AST2400_SCU_BASE 0x1E6E2000
> -#define AST2400_TIMER_BASE   0x1E782000
> -#define AST2400_I2C_BASE 0x1E78A000
> -
> -#define AST2400_FMC_FLASH_BASE   0x2000
> -#define AST2400_SPI_FLASH_BASE   0x3000
> +#define ASPEED_SOC_UART_5_BASE  0x00184000
> +#define ASPEED_SOC_IOMEM_SIZE   0x0020
> +#define ASPEED_SOC_IOMEM_BASE   0x1E60
> +#define ASPEED_SOC_FMC_BASE 0x1E62
> +#define ASPEED_SOC_SPI_BASE 0x1E63
> +#define ASPEED_SOC_VIC_BASE 0x1E6C
> +#define ASPEED_SOC_SDMC_BASE0x1E6E
> +#define ASPEED_SOC_SCU_BASE 0x1E6E2000
> +#define ASPEED_SOC_TIMER_BASE   0x1E782000
> +#define ASPEED_SOC_I2C_BASE 0x1E78A000
> +
> +#define ASPEED_SOC_FMC_FLASH_BASE   0x2000
> +#define ASPEED_SOC_SPI_FLASH_BASE   0x3000
>  
>  static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
>  static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
> @@ -43,29 +42,29 @@ static const int timer_irqs[] = { 16, 17, 18, 35,
> 36, 37, 38, 39, };
>   * handled by a device mapping.
>   */
>  
> -static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned
> size)
> +static uint64_t aspeed_soc_io_read(void *p, hwaddr offset, unsigned
> size)
>  {
>  qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
>    __func__, offset, size);
>  return 0;
>  }
>  
> -static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t
> value,
> +static void aspeed_soc_io_write(void *opaque, hwaddr offset,
> uint64_t value,
>  unsigned size)
>  {
>  qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64
> " [%u]\n",
>    __func__, offset, value, size);
>  }
>  
> -static const MemoryRegionOps ast2400_io_ops = {
> -.read = ast2400_io_read,
> -.write = ast2400_io_write,
> +static const MemoryRegionOps aspeed_soc_io_ops = {
> +.read = aspeed_soc_io_read,
> +.write = aspeed_soc_io_write,
>  .endianness = DEVICE_LITTLE_ENDIAN,
>  };
>  
> -static void ast2400_init(Object *obj)
> +static void aspeed_soc_init(Object *obj)
>  {
> -AST2400State *s = AST2400(obj);
> +AspeedSoCState *s = ASPEED_SOC(obj);
>  
>  s->cpu = cpu_arm_init("arm926");
>  
> @@ -106,17 +105,17 @@ static void ast2400_init(Object *obj)
>   AST2400_A0_SILICON_REV);
>  }
>  
> -static void ast2400_realize(DeviceState *dev, Error **errp)
> +static void aspeed_soc_realize(DeviceState *dev, Error **errp)
>  {
>  int i;
> -AST2400State *s = AST2400(dev);
> +AspeedSoCState *s = ASPEED_SOC(dev);
>  Error *err = NULL, *local_err = NULL;
>  
>  /* IO space */
> -memory_region_init_io(>iomem, NULL, _io_ops, NULL,
> -"ast2400.io", AST2400_IOMEM_SIZE);
> -memory_region_add_subregion_overlap(get_system_memory(),
> AST2400_IOMEM_BASE,
> ->iomem, -1);
> +memory_region_init_io(>iomem, NULL, _soc_io_ops, NULL,
> +  

Re: [Qemu-devel] [PATCH v3 01/10] ast2400: rename the Aspeed SoC files to aspeed_soc

2016-08-02 Thread Andrew Jeffery
On Tue, 2016-08-02 at 19:15 +0200, Cédric Le Goater wrote:
> Let's prepare for new Aspeed SoCs and rename the ast2400 file to a
> more generic one. There are no changes in the code apart from the
> header file include.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/arm/Makefile.objs|   2 +-
>  hw/arm/aspeed_soc.c | 229
> 
>  hw/arm/ast2400.c| 229 --
> --
>  hw/arm/palmetto-bmc.c   |   2 +-
>  include/hw/arm/aspeed_soc.h |  44 +
>  include/hw/arm/ast2400.h|  44 -
>  6 files changed, 275 insertions(+), 275 deletions(-)
>  create mode 100644 hw/arm/aspeed_soc.c
>  delete mode 100644 hw/arm/ast2400.c
>  create mode 100644 include/hw/arm/aspeed_soc.h
>  delete mode 100644 include/hw/arm/ast2400.h
> 
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 12764ef2b719..7901294630b1 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -17,4 +17,4 @@ obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-
> ep108.o
>  obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
>  obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
>  obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
> -obj-$(CONFIG_ASPEED_SOC) += ast2400.o palmetto-bmc.o
> +obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o palmetto-bmc.o
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> new file mode 100644
> index ..b272f4e48cfc
> --- /dev/null
> +++ b/hw/arm/aspeed_soc.c
> @@ -0,0 +1,229 @@
> +/*
> + * AST2400 SoC
> + *
> + * Andrew Jeffery <and...@aj.id.au>
> + * Jeremy Kerr <j...@ozlabs.org>
> + *
> + * Copyright 2016 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 "qapi/error.h"
> +#include "qemu-common.h"
> +#include "cpu.h"
> +#include "exec/address-spaces.h"
> +#include "hw/arm/aspeed_soc.h"
> +#include "hw/char/serial.h"
> +#include "qemu/log.h"
> +#include "hw/i2c/aspeed_i2c.h"
> +
> +#define AST2400_UART_5_BASE  0x00184000
> +#define AST2400_IOMEM_SIZE   0x0020
> +#define AST2400_IOMEM_BASE   0x1E60
> +#define AST2400_SMC_BASE AST2400_IOMEM_BASE /* Legacy SMC */
> +#define AST2400_FMC_BASE 0X1E62
> +#define AST2400_SPI_BASE 0X1E63
> +#define AST2400_VIC_BASE 0x1E6C
> +#define AST2400_SDMC_BASE0x1E6E
> +#define AST2400_SCU_BASE 0x1E6E2000
> +#define AST2400_TIMER_BASE   0x1E782000
> +#define AST2400_I2C_BASE 0x1E78A000
> +
> +#define AST2400_FMC_FLASH_BASE   0x2000
> +#define AST2400_SPI_FLASH_BASE   0x3000
> +
> +static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
> +static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
> +
> +/*
> + * IO handlers: simply catch any reads/writes to IO addresses that
> aren't
> + * handled by a device mapping.
> + */
> +
> +static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned
> size)
> +{
> +qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
> +  __func__, offset, size);
> +return 0;
> +}
> +
> +static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t
> value,
> +unsigned size)
> +{
> +qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64
> " [%u]\n",
> +  __func__, offset, value, size);
> +}
> +
> +static const MemoryRegionOps ast2400_io_ops = {
> +.read = ast2400_io_read,
> +.write = ast2400_io_write,
> +.endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> +static void ast2400_init(Object *obj)
> +{
> +AST2400State *s = AST2400(obj);
> +
> +s->cpu = cpu_arm_init("arm926");
> +
> +object_initialize(>vic, sizeof(s->vic), TYPE_ASPEED_VIC);
> +object_property_add_child(obj, "vic", OBJECT(>vic), NULL);
> +qdev_set_parent_bus(DEVICE(>vic), sysbus_get_default());
> +
> +object_initialize(>timerctrl, sizeof(s->timerctrl),
> TYPE_ASPEED_TIMER);
> +object_property_add_child(obj, "timerctrl", OBJECT(
> >timerctrl), NULL);
> +qdev_set_parent_bus(DEVICE(>timerctrl),
> sysbus_get_default());
> +
> +object_initialize(>i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
> +object_property_add_child(obj, "i2c", OBJECT(

Re: [Qemu-devel] [PATCH 1/6] palmetto-bmc: add a "silicon-rev" property at the soc level

2016-07-31 Thread Andrew Jeffery
On Sat, 2016-07-30 at 10:35 +0200, Cédric Le Goater wrote:
> On 07/29/2016 03:16 AM, Andrew Jeffery wrote:
> > 
> > On Thu, 2016-07-28 at 09:51 +0200, Cédric Le Goater wrote:
> > > 
> > > On 07/28/2016 04:14 AM, Andrew Jeffery wrote:
> > > > 
> > > > 
> > > > On Wed, 2016-07-27 at 18:46 +0200, Cédric Le Goater wrote:
> > > > > 
> > > > > 
> > > > > The SCU controler holds the board revision number in its 0x7C
> > > > > register. Let's use an alias to link a "silicon-rev" property of the
> > > > > soc to the "silicon-rev" property of the SCU controler.
> > > > > 
> > > > > The SDMC controler "silicon-rev" property is derived from the SCU one
> > > > > at realize time. I did not find a better way to handle this part.
> > > > > Links and aliases being a one-to-one relation, I could not use one of
> > > > > them. I might wrong though.
> > > > Are we trying to over-use the silicon-rev value (it would seem so at
> > > > least in the face of the link/alias constraints)? We know which SDMC
> > > > revision we need for each SoC and we'll be modelling an explicit SoC
> > > > revision, so should we instead set a separate property on the SDMC in
> > > > the SoCs' respective initialise functions (and leave silicon-rev to the
> > > > SCU)? 
> > > This is the case. no ? 
> > No, because you are selecting the SDMC configuration from the silicon-
> > rev rather than letting e.g. the SDMC configuration define which
> > silicon-rev the SoC takes.
> > 
> > My thinking is the silicon rev is a property of the SoC. The platform
> > should select a SoC to use and not be setting silicon revision values,
> > that is I think it's a layering violation for the platform to be
> > setting the silicon-rev (and also the CPU).
> > 
> > We also wind up in a situation where the ast2500 soc identifies as an
> > ast2400 in TypeInfo.name due to the approach to reuse by this series.
> OK. To be cleaner, we could add a AspeedSoCClass and a set of predefined 
> subclasses for each revision we support, that we would instantiate at the 
> platform level.

Yes - an AspeedSocClass is the way I went when I briefly started to
sketch out a patch to make my thoughts more concrete.

>   
> The AspeedSocClass would be similar to the AspeedBoardConfig struct in 
> the current patchset, plus the cpu model. How would that be ?  

Sounds good to me, though hw-strap1 still needs to be set by the
platform and not the SoC.

>  
> 
> > 
> > > 
> > > SCU holds the silicon-rev value. The patch adds a property alias to the 
> > > SCU 'silicon-rev' property at the soc level. This is convenient
> > Right, but "convenient" here is a bit of a stretch given we are
> > subsequently fetching the value out of the SCU to select the SDMC
> > configuration. You might argue that it's due to limitations of the
> > property alias/link API, but maybe we could rearrange things so this
> > goes away.
> yes that would be nicer not to have to re-set the silicon rev of the 
> controllers of a SoC.
> 
> > 
> > > 
> > >  for the
> > > platform to initialize the soc. This is similar to what the rpi2 does,
> > > which goes one level in the aliasing.
> > Okay, maybe I'm barking up trees unnecessarily.
> No. your point on the SoC reuse is very valid. I try not to overspecify 
> too early but I agree I took a little shortcut. I will kick a v3 with
> the above. It should not be too much of a change.
> 
> > 
> > > 
> > > Then, at initialize time, the SCU 'silicon-rev' property value is read
> > > to initialize the SDMC controller. If we have more controllers in the 
> > > future needing 'silicon-rev,  we could follow the same pattern. Not 
> > > saying this is perfect. 
> > > 
> > > What I would have liked to do, is to link all the 'silicon-rev' do
> > > the SCU one. I did not find a way.
> > Yes, that would be nice. I did briefly poke around to see if there was
> > a solution to the link/alias issue but it seems not. 
> > 
> > > 
> > > 
> > > > 
> > > > 
> > > > My thought was the silicon-rev value is reflective of the SoC
> > > > design rather than the other way around - but maybe that's splitting
> > > > hairs. 
> > > ah. is your concern about which object is holding the value ? If so,
> > > I thought that keeping it where it belongs on real HW wa

Re: [Qemu-devel] [PATCH 1/6] palmetto-bmc: add a "silicon-rev" property at the soc level

2016-07-28 Thread Andrew Jeffery
On Thu, 2016-07-28 at 09:51 +0200, Cédric Le Goater wrote:
> On 07/28/2016 04:14 AM, Andrew Jeffery wrote:
> > 
> > On Wed, 2016-07-27 at 18:46 +0200, Cédric Le Goater wrote:
> > > 
> > > The SCU controler holds the board revision number in its 0x7C
> > > register. Let's use an alias to link a "silicon-rev" property of the
> > > soc to the "silicon-rev" property of the SCU controler.
> > > 
> > > The SDMC controler "silicon-rev" property is derived from the SCU one
> > > at realize time. I did not find a better way to handle this part.
> > > Links and aliases being a one-to-one relation, I could not use one of
> > > them. I might wrong though.
> > Are we trying to over-use the silicon-rev value (it would seem so at
> > least in the face of the link/alias constraints)? We know which SDMC
> > revision we need for each SoC and we'll be modelling an explicit SoC
> > revision, so should we instead set a separate property on the SDMC in
> > the SoCs' respective initialise functions (and leave silicon-rev to the
> > SCU)? 
> This is the case. no ? 

No, because you are selecting the SDMC configuration from the silicon-
rev rather than letting e.g. the SDMC configuration define which
silicon-rev the SoC takes.

My thinking is the silicon rev is a property of the SoC. The platform
should select a SoC to use and not be setting silicon revision values,
that is I think it's a layering violation for the platform to be
setting the silicon-rev (and also the CPU).

We also wind up in a situation where the ast2500 soc identifies as an
ast2400 in TypeInfo.name due to the approach to reuse by this series.

> 
> SCU holds the silicon-rev value. The patch adds a property alias to the 
> SCU 'silicon-rev' property at the soc level. This is convenient

Right, but "convenient" here is a bit of a stretch given we are
subsequently fetching the value out of the SCU to select the SDMC
configuration. You might argue that it's due to limitations of the
property alias/link API, but maybe we could rearrange things so this
goes away.

>  for the
> platform to initialize the soc. This is similar to what the rpi2 does,
> which goes one level in the aliasing.

Okay, maybe I'm barking up trees unnecessarily.

> 
> Then, at initialize time, the SCU 'silicon-rev' property value is read
> to initialize the SDMC controller. If we have more controllers in the 
> future needing 'silicon-rev,  we could follow the same pattern. Not 
> saying this is perfect. 
> 
> What I would have liked to do, is to link all the 'silicon-rev' do
> the SCU one. I did not find a way.

Yes, that would be nice. I did briefly poke around to see if there was
a solution to the link/alias issue but it seems not. 

> 
> > 
> > My thought was the silicon-rev value is reflective of the SoC
> > design rather than the other way around - but maybe that's splitting
> > hairs. 
> ah. is your concern about which object is holding the value ? If so,
> I thought that keeping it where it belongs on real HW was the better 
> option, that is in SCU, and then build from there.

No, that's not my concern, but I agree that it would not reflect the
hardware if there was a property on the SoC (i.e. there is nowhere
besides the SCU that the value is held).

> 
> > 
> > It would also be trading off a bit of ugliness in this patch for
> > potential bugs if the properties get out of sync.
> This is the exact the purpose of the patch ! I failed to make it feel
> that way :)

Right. I think we need another layer of abstraction, essentially a soc
configuration struct that is accessed by what are currently the
ast2400_{init,realise}() functions. This will capture differences like
changes in IO addresses, changes to IP behaviour, the CPU types and
ultimately the silicon-rev value. What is now ast2400_init() and
ast2400_realise() can become generic aspeed_soc_{init,realise}(), and
then we wrap calls to this up in SoC-specific
ast2{4,5}00_{init,realise}() where we set the configuration struct. It
is a bit more work but I think the result would better reflect the
hardware and avoid introducing what feel to me like layering
violations.

Thoughts?

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 6/6] arm: add support for an ast2500 evaluation board

2016-07-28 Thread Andrew Jeffery
On Thu, 2016-07-28 at 09:15 +0200, Cédric Le Goater wrote:
> > 
> > Also, the meaning of the bits have changed from the AST2400 - they
> > probably should be documented somewhere?
> 
> So you want me send to an updated version of :
> 
> http://lists.nongnu.org/archive/html/qemu-arm/2016-06/msg00698.html
> 
> as a prereq ? 

I mentioned this in passing due to the discussion on my original patch.
I think we discussed this separately and concluded the macros were
pretty verbose given they are sort-of single-use given the value
doesn't change. Maybe just comments as Peter was requesting? You have
the patch below but some of the macros will be different for the
AST2500.

I'm probably leaning towards comments over macros, but don't feel
strongly either way.

Andrew

> 
> Now that we have done the cleanups in U-Boot, we can pull from :
> 
> https://github.com/openbmc/u-boot/blob/v2016.07-aspeed-openbmc/arch/arm/include/asm/arch-aspeed/regs-scu.h
> 
> to get the definitions. I will add that.

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 6/6] arm: add support for an ast2500 evaluation board

2016-07-27 Thread Andrew Jeffery
On Wed, 2016-07-27 at 18:46 +0200, Cédric Le Goater wrote:
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/arm/palmetto-bmc.c| 32 +++-
>  include/hw/arm/ast2400.h |  5 +
>  2 files changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
> index cd8aa59756b9..8d8bfeb571e2 100644
> --- a/hw/arm/palmetto-bmc.c
> +++ b/hw/arm/palmetto-bmc.c
> @@ -37,12 +37,15 @@ typedef struct AspeedBoardConfig {
>  } AspeedBoardConfig;
>  
>  enum {
> -PALMETTO_BMC
> +PALMETTO_BMC,
> +AST2500_EDK

It was called 'ast2500-edk' in the out-of-tree patches, but can we
rename it 'ast2500-evb'? This would make it consistent with patches we
have in our Linux trees.

>  };
>  
>  static const AspeedBoardConfig aspeed_boards[] = {
>  [ PALMETTO_BMC ] = { 0x120CE416, AST2400_A0_SILICON_REV,
>   AST2400_SDRAM_BASE },
> +[ AST2500_EDK ]  = { 0x0200, AST2500_A1_SILICON_REV,
> + AST2500_SDRAM_BASE },

Can we include the strap value from the board for completeness?

Also, the meaning of the bits have changed from the AST2400 - they
probably should be documented somewhere?

Finally, checkpatch complained here too regarding the whitespace, I ran
into the issue replacing the strap value.

>  };
>  
>  static void aspeed_init_flashes(AspeedSMCState *s, const char *flashtype,
> @@ -133,9 +136,36 @@ static const TypeInfo palmetto_bmc_type = {
>  .class_init = palmetto_bmc_class_init,
>  };
>  
> +static void ast2500_edk_init(MachineState *machine)
> +{
> +machine->cpu_model = "arm1176";
> +aspeed_init(machine, AST2500_EDK);
> +}
> +
> +static void ast2500_edk_class_init(ObjectClass *oc, void *data)
> +{
> +MachineClass *mc = MACHINE_CLASS(oc);
> +
> +mc->desc = "Aspeed AST2500 EDK (ARM1176)";
> +mc->init = ast2500_edk_init;
> +mc->max_cpus = 1;
> +mc->no_sdcard = 1;
> +mc->no_floppy = 1;
> +mc->no_cdrom = 1;
> +mc->no_sdcard = 1;

mc->no_sdcard is already assigned a couple of lines up. I think this
may be the case for palmetto config as well...

Cheers,

Andrew

> +mc->no_parallel = 1;
> +}
> +
> +static const TypeInfo ast2500_edk_type = {
> +.name = MACHINE_TYPE_NAME("ast2500-edk"),
> +.parent = TYPE_MACHINE,
> +.class_init = ast2500_edk_class_init,
> +};
> +
>  static void aspeed_machine_init(void)
>  {
>  type_register_static(_bmc_type);
> +type_register_static(_edk_type);
>  }
>  
>  type_init(aspeed_machine_init)
> diff --git a/include/hw/arm/ast2400.h b/include/hw/arm/ast2400.h
> index e68807d475b7..2e6864f88790 100644
> --- a/include/hw/arm/ast2400.h
> +++ b/include/hw/arm/ast2400.h
> @@ -41,4 +41,9 @@ typedef struct AST2400State {
>  
>  #define AST2400_SDRAM_BASE   0x4000
>  
> +/*
> + * for Aspeed AST2500 SOC and higher
> + */
> +#define AST2500_SDRAM_BASE   0x8000
> +
>  #endif /* AST2400_H */

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 2/6] palmetto-bmc: replace palmetto_bmc with aspeed

2016-07-27 Thread Andrew Jeffery
On Wed, 2016-07-27 at 18:46 +0200, Cédric Le Goater wrote:
> This is mostly a name replacement to prepare ground for other socs
> specificities. It also adds a specific TypeInfo struct for the
> palmetto_bmc board with a custom initialization for the same reason.

I think we should rename the file, it feels a bit confusing having the
ast2500 machine glue (added later in the series) in palmetto-bmc.c. You
mentioned in the cover letter that moving it would break history but it
isn't necessarily so, you can follow renames in the logs with `git log
--follow`. It's a git switch that feels like it should be a default but
isn't :/

Maybe create a commit that renames the file, then add these changes
after?

Andrew

> 
> Signed-off-by: Cédric Le Goater 
> ---
> 
>  Should we change the name of the file to aspeed.c ? I am not found of
>  such renames as it is then difficult to track code changes.
> 
>  hw/arm/palmetto-bmc.c | 54 
> ++-
>  1 file changed, 36 insertions(+), 18 deletions(-)
> 
> diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
> index 1ee13d578899..f80a15733864 100644
> --- a/hw/arm/palmetto-bmc.c
> +++ b/hw/arm/palmetto-bmc.c
> @@ -21,19 +21,19 @@
>  #include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  
> -static struct arm_boot_info palmetto_bmc_binfo = {
> +static struct arm_boot_info aspeed_binfo = {
>  .loader_start = AST2400_SDRAM_BASE,
>  .board_id = 0,
>  .nb_cpus = 1,
>  };
>  
> -typedef struct PalmettoBMCState {
> +typedef struct AspeedBoardState {
>  AST2400State soc;
>  MemoryRegion ram;
> -} PalmettoBMCState;
> +} AspeedBoardState;
>  
> -static void palmetto_bmc_init_flashes(AspeedSMCState *s, const char 
> *flashtype,
> -  Error **errp)
> +static void aspeed_init_flashes(AspeedSMCState *s, const char *flashtype,
> +Error **errp)
>  {
>  int i ;
>  
> @@ -58,11 +58,11 @@ static void palmetto_bmc_init_flashes(AspeedSMCState *s, 
> const char *flashtype,
>  }
>  }
>  
> -static void palmetto_bmc_init(MachineState *machine)
> +static void aspeed_init(MachineState *machine)
>  {
> -PalmettoBMCState *bmc;
> +AspeedBoardState *bmc;
>  
> -bmc = g_new0(PalmettoBMCState, 1);
> +bmc = g_new0(AspeedBoardState, 1);
>  object_initialize(>soc, (sizeof(bmc->soc)), TYPE_AST2400);
>  object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
>    _abort);
> @@ -79,19 +79,26 @@ static void palmetto_bmc_init(MachineState *machine)
>  object_property_set_bool(OBJECT(>soc), true, "realized",
>   _abort);
>  
> -palmetto_bmc_init_flashes(>soc.smc, "n25q256a", _abort);
> -palmetto_bmc_init_flashes(>soc.spi, "mx25l25635e", _abort);
> +aspeed_init_flashes(>soc.smc, "n25q256a", _abort);
> +aspeed_init_flashes(>soc.spi, "mx25l25635e", _abort);
> +
> +aspeed_binfo.kernel_filename = machine->kernel_filename;
> +aspeed_binfo.initrd_filename = machine->initrd_filename;
> +aspeed_binfo.kernel_cmdline = machine->kernel_cmdline;
> +aspeed_binfo.ram_size = ram_size;
> +arm_load_kernel(ARM_CPU(first_cpu), _binfo);
> +}
>  
> -palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
> -palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
> -palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
> -palmetto_bmc_binfo.ram_size = ram_size;
> -arm_load_kernel(ARM_CPU(first_cpu), _bmc_binfo);
> +static void palmetto_bmc_init(MachineState *machine)
> +{
> +aspeed_init(machine);
>  }
>  
> -static void palmetto_bmc_machine_init(MachineClass *mc)
> +static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
>  {
> -mc->desc = "OpenPOWER Palmetto BMC";
> +MachineClass *mc = MACHINE_CLASS(oc);
> +
> +mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
>  mc->init = palmetto_bmc_init;
>  mc->max_cpus = 1;
>  mc->no_sdcard = 1;
> @@ -101,4 +108,15 @@ static void palmetto_bmc_machine_init(MachineClass *mc)
>  mc->no_parallel = 1;
>  }
>  
> -DEFINE_MACHINE("palmetto-bmc", palmetto_bmc_machine_init);
> +static const TypeInfo palmetto_bmc_type = {
> +.name = MACHINE_TYPE_NAME("palmetto-bmc"),
> +.parent = TYPE_MACHINE,
> +.class_init = palmetto_bmc_class_init,
> +};
> +
> +static void aspeed_machine_init(void)
> +{
> +type_register_static(_bmc_type);
> +}
> +
> +type_init(aspeed_machine_init)

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 5/6] aspeed: add ast2500 support to scu and sdmc controllers

2016-07-27 Thread Andrew Jeffery
On Wed, 2016-07-27 at 18:46 +0200, Cédric Le Goater wrote:
> Based on previous work done by Andrew Jeffery <and...@aj.id.au>.
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

> ---
>  hw/misc/aspeed_scu.c | 45 
> +++-
>  hw/misc/aspeed_sdmc.c|  1 +
>  include/hw/misc/aspeed_scu.h |  1 +
>  3 files changed, 46 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> index c7e2c8263f55..6dd7e1085420 100644
> --- a/hw/misc/aspeed_scu.c
> +++ b/hw/misc/aspeed_scu.c
> @@ -120,6 +120,41 @@ static const uint32_t 
> ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
>   [BMC_DEV_ID]  = 0x2402U
>  };
>  
> +/* SCU70 bit 23: 0 24Mhz. bit 11:9: 0b001 AXI:ABH ratio 2:1 */
> +/* AST2500 revision A1 */
> +
> +static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
> + [SYS_RST_CTRL]= 0xFFCFFEDCU,
> + [CLK_SEL] = 0xF3F4U,
> + [CLK_STOP_CTRL]   = 0x19FC3E8BU,
> + [D2PLL_PARAM] = 0x00026108U,
> + [MPLL_PARAM]  = 0x00030291U,
> + [HPLL_PARAM]  = 0x93000400U,
> + [MISC_CTRL1]  = 0x0010U,
> + [PCI_CTRL1]   = 0x20001A03U,
> + [PCI_CTRL2]   = 0x20001A03U,
> + [PCI_CTRL3]   = 0x0430U,
> + [SYS_RST_STATUS]  = 0x0001U,
> + [SOC_SCRATCH1]= 0x00C0U, /* SoC completed DRAM init */
> + [MISC_CTRL2]  = 0x0023U,
> + [RNG_CTRL]= 0x000EU,
> + [PINMUX_CTRL2]= 0xF000U,
> + [PINMUX_CTRL3]= 0x0300U,
> + [PINMUX_CTRL4]= 0xU,
> + [PINMUX_CTRL5]= 0xA000U,
> + [WDT_RST_CTRL]= 0x0233U,
> + [PINMUX_CTRL8]= 0xU,
> + [PINMUX_CTRL9]= 0x000FU,
> + [FREE_CNTR4]  = 0x00FFU,
> + [FREE_CNTR4_EXT]  = 0x00FFU,
> + [CPU2_BASE_SEG1]  = 0x8000U,
> + [CPU2_BASE_SEG4]  = 0x1E60U,
> + [CPU2_BASE_SEG5]  = 0xC000U,
> + [UART_HPLL_CLK]   = 0x1903U,
> + [PCIE_CTRL]   = 0x007BU,
> + [BMC_DEV_ID]  = 0x2402U
> +};
> +
>  static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
>  {
>  AspeedSCUState *s = ASPEED_SCU(opaque);
> @@ -198,6 +233,10 @@ static void aspeed_scu_reset(DeviceState *dev)
>  case AST2400_A0_SILICON_REV:
>  reset = ast2400_a0_resets;
>  break;
> +case AST2500_A0_SILICON_REV:
> +case AST2500_A1_SILICON_REV:
> +reset = ast2500_a1_resets;
> +break;
>  default:
>  g_assert_not_reached();
>  }
> @@ -208,7 +247,11 @@ static void aspeed_scu_reset(DeviceState *dev)
>  s->regs[HW_STRAP2] = s->hw_strap2;
>  }
>  
> -static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, };
> +static uint32_t aspeed_silicon_revs[] = {
> +AST2400_A0_SILICON_REV,
> +AST2500_A0_SILICON_REV,
> +AST2500_A1_SILICON_REV
> +};
>  
>  bool is_supported_silicon_rev(uint32_t silicon_rev)
>  {
> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
> index 6cc0301a6331..621d166890fa 100644
> --- a/hw/misc/aspeed_sdmc.c
> +++ b/hw/misc/aspeed_sdmc.c
> @@ -196,6 +196,7 @@ static void aspeed_sdmc_reset(DeviceState *dev)
>  break;
>  
>  case AST2500_A0_SILICON_REV:
> +case AST2500_A1_SILICON_REV:
>  s->regs[R_CONF] |=
>  ASPEED_SDMC_HW_VERSION(1) |
>  ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
> diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
> index fdfd982288f2..e2e4d1864e34 100644
> --- a/include/hw/misc/aspeed_scu.h
> +++ b/include/hw/misc/aspeed_scu.h
> @@ -33,6 +33,7 @@ typedef struct AspeedSCUState {
>  
>  #define AST2400_A0_SILICON_REV   0x02000303U
>  #define AST2500_A0_SILICON_REV   0x04000303U
> +#define AST2500_A1_SILICON_REV   0x04010303U
>  
>  extern bool is_supported_silicon_rev(uint32_t silicon_rev);
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 4/6] palmetto-bmc: add board specific configuration

2016-07-27 Thread Andrew Jeffery
On Wed, 2016-07-27 at 18:46 +0200, Cédric Le Goater wrote:
> aspeed_init() now uses a board identifier to customize some values
> specific to the board, ram base, board revision number, etc.
> 
> Signed-off-by: Cédric Le Goater 

Looks okay to me, some minor comments below:

> ---
>  hw/arm/palmetto-bmc.c | 34 ++
>  1 file changed, 26 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
> index 8a3ff5568575..cd8aa59756b9 100644
> --- a/hw/arm/palmetto-bmc.c
> +++ b/hw/arm/palmetto-bmc.c
> @@ -22,8 +22,6 @@
>  #include "sysemu/blockdev.h"
>  
>  static struct arm_boot_info aspeed_binfo = {
> -.loader_start = AST2400_SDRAM_BASE,
> -.board_id = 0,
>  .nb_cpus = 1,
>  };
>  
> @@ -32,6 +30,21 @@ typedef struct AspeedBoardState {
>  MemoryRegion ram;
>  } AspeedBoardState;
>  
> +typedef struct AspeedBoardConfig {
> +uint32_t hw_strap1;
> +uint32_t silicon_rev;
> +hwaddr sdram_base;
> +} AspeedBoardConfig;
> +
> +enum {
> +PALMETTO_BMC
> +};
> +
> +static const AspeedBoardConfig aspeed_boards[] = {
> +[ PALMETTO_BMC ] = { 0x120CE416, AST2400_A0_SILICON_REV,
> + AST2400_SDRAM_BASE },

I was playing around before and my test scripts noticed checkpatch
complained about the spacing with the array indexing: "[PALMETTO_BMC]"
fixed the error.

> +};
> +
>  static void aspeed_init_flashes(AspeedSMCState *s, const char *flashtype,
>  Error **errp)
>  {
> @@ -58,7 +71,7 @@ static void aspeed_init_flashes(AspeedSMCState *s, const 
> char *flashtype,
>  }
>  }
>  
> -static void aspeed_init(MachineState *machine)
> +static void aspeed_init(MachineState *machine, int board_model)

I feel like we should pass a "struct AspeedBoardConfig *" rather than
the "int board_model", cleaning up the repeated indexing into
aspeed_boards the body. Thoughts? 

Andrew

>  {
>  AspeedBoardState *bmc;
>  
> @@ -68,13 +81,16 @@ static void aspeed_init(MachineState *machine)
>    _abort);
>  
>  memory_region_allocate_system_memory(>ram, NULL, "ram", ram_size);
> -memory_region_add_subregion(get_system_memory(), AST2400_SDRAM_BASE,
> +memory_region_add_subregion(get_system_memory(),
> +aspeed_boards[board_model].sdram_base,
>  >ram);
>  object_property_add_const_link(OBJECT(>soc), "ram", 
> OBJECT(>ram),
> _abort);
> -object_property_set_int(OBJECT(>soc), 0x120CE416, "hw-strap1",
> -_abort);
> -object_property_set_int(OBJECT(>soc), AST2400_A0_SILICON_REV,
> +object_property_set_int(OBJECT(>soc),
> +aspeed_boards[board_model].hw_strap1,
> +"hw-strap1", _abort);
> +object_property_set_int(OBJECT(>soc),
> +aspeed_boards[board_model].silicon_rev,
>  "silicon-rev", _abort);
>  object_property_set_bool(OBJECT(>soc), true, "realized",
>   _abort);
> @@ -86,13 +102,15 @@ static void aspeed_init(MachineState *machine)
>  aspeed_binfo.initrd_filename = machine->initrd_filename;
>  aspeed_binfo.kernel_cmdline = machine->kernel_cmdline;
>  aspeed_binfo.ram_size = ram_size;
> +aspeed_binfo.loader_start = aspeed_boards[board_model].sdram_base,
> +aspeed_binfo.board_id = aspeed_boards[board_model].silicon_rev,
>  arm_load_kernel(ARM_CPU(first_cpu), _binfo);
>  }
>  
>  static void palmetto_bmc_init(MachineState *machine)
>  {
>  machine->cpu_model = "arm926";
> -aspeed_init(machine);
> +aspeed_init(machine, PALMETTO_BMC);
>  }
>  
>  static void palmetto_bmc_class_init(ObjectClass *oc, void *data)

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 3/6] ast2400: use machine cpu_model to initialize the soc cpu

2016-07-27 Thread Andrew Jeffery
On Wed, 2016-07-27 at 18:46 +0200, Cédric Le Goater wrote:
> It will be easier to specify a different cpu for other soc derived
> from the ast2400 soc.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/arm/ast2400.c  | 8 +++-
>  hw/arm/palmetto-bmc.c | 1 +
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
> index fa535065f765..7f3517a2c6c6 100644
> --- a/hw/arm/ast2400.c
> +++ b/hw/arm/ast2400.c
> @@ -15,6 +15,7 @@
>  #include "qemu-common.h"
>  #include "cpu.h"
>  #include "exec/address-spaces.h"
> +#include "hw/boards.h"
>  #include "hw/arm/ast2400.h"
>  #include "hw/char/serial.h"
>  #include "qemu/log.h"
> @@ -65,9 +66,14 @@ static const MemoryRegionOps ast2400_io_ops = {
>  
>  static void ast2400_init(Object *obj)
>  {
> +const char *cpu_model = current_machine->cpu_model;
>  AST2400State *s = AST2400(obj);
>  
> -s->cpu = cpu_arm_init("arm926");
> +if (!cpu_model) {
> +cpu_model = "arm926";
> +}
> +
> +s->cpu = cpu_arm_init(cpu_model);

I did a similar thing in the series introducing the AST2400 SoC, and
Peter had a comment on the approach[1]:

What we do now is not let the user override the cpu model at all;
presumably this SoC only ever has an ARM926 and it doesn't make
any sense to have some frankenstein "this SoC but with a different
CPU in it" config.

Given this is the ast2400_init() it looks to me like we should be
hardwiring the CPU rather than leaving it to the machine to define.

[1] https://patchwork.kernel.org/patch/8325651/ 

>  
>  object_initialize(>vic, sizeof(s->vic), TYPE_ASPEED_VIC);
>  object_property_add_child(obj, "vic", OBJECT(>vic), NULL);
> diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
> index f80a15733864..8a3ff5568575 100644
> --- a/hw/arm/palmetto-bmc.c
> +++ b/hw/arm/palmetto-bmc.c
> @@ -91,6 +91,7 @@ static void aspeed_init(MachineState *machine)
>  
>  static void palmetto_bmc_init(MachineState *machine)
>  {
> +machine->cpu_model = "arm926";
>  aspeed_init(machine);
>  }
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 1/6] palmetto-bmc: add a "silicon-rev" property at the soc level

2016-07-27 Thread Andrew Jeffery
On Wed, 2016-07-27 at 18:46 +0200, Cédric Le Goater wrote:
> The SCU controler holds the board revision number in its 0x7C
> register. Let's use an alias to link a "silicon-rev" property of the
> soc to the "silicon-rev" property of the SCU controler.
> 
> The SDMC controler "silicon-rev" property is derived from the SCU one
> at realize time. I did not find a better way to handle this part.
> Links and aliases being a one-to-one relation, I could not use one of
> them. I might wrong though.

Are we trying to over-use the silicon-rev value (it would seem so at
least in the face of the link/alias constraints)? We know which SDMC
revision we need for each SoC and we'll be modelling an explicit SoC
revision, so should we instead set a separate property on the SDMC in
the SoCs' respective initialise functions (and leave silicon-rev to the
SCU)? My thought was the silicon-rev value is reflective of the SoC
design rather than the other way around - but maybe that's splitting
hairs. It would also be trading off a bit of ugliness in this patch for
potential bugs if the properties get out of sync.

Cheers,

Andrew

> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/arm/ast2400.c  | 18 +-
>  hw/arm/palmetto-bmc.c |  2 ++
>  2 files changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
> index 136bf6464e1d..fa535065f765 100644
> --- a/hw/arm/ast2400.c
> +++ b/hw/arm/ast2400.c
> @@ -84,8 +84,8 @@ static void ast2400_init(Object *obj)
>  object_initialize(>scu, sizeof(s->scu), TYPE_ASPEED_SCU);
>  object_property_add_child(obj, "scu", OBJECT(>scu), NULL);
>  qdev_set_parent_bus(DEVICE(>scu), sysbus_get_default());
> -qdev_prop_set_uint32(DEVICE(>scu), "silicon-rev",
> - AST2400_A0_SILICON_REV);
> +object_property_add_alias(obj, "silicon-rev", OBJECT(>scu),
> +  "silicon-rev", _abort);
>  object_property_add_alias(obj, "hw-strap1", OBJECT(>scu),
>    "hw-strap1", _abort);
>  object_property_add_alias(obj, "hw-strap2", OBJECT(>scu),
> @@ -102,8 +102,6 @@ static void ast2400_init(Object *obj)
>  object_initialize(>sdmc, sizeof(s->sdmc), TYPE_ASPEED_SDMC);
>  object_property_add_child(obj, "sdmc", OBJECT(>sdmc), NULL);
>  qdev_set_parent_bus(DEVICE(>sdmc), sysbus_get_default());
> -qdev_prop_set_uint32(DEVICE(>sdmc), "silicon-rev",
> - AST2400_A0_SILICON_REV);
>  }
>  
>  static void ast2400_realize(DeviceState *dev, Error **errp)
> @@ -111,6 +109,7 @@ static void ast2400_realize(DeviceState *dev, Error 
> **errp)
>  int i;
>  AST2400State *s = AST2400(dev);
>  Error *err = NULL, *local_err = NULL;
> +uint32_t silicon_rev;
>  
>  /* IO space */
>  memory_region_init_io(>iomem, NULL, _io_ops, NULL,
> @@ -192,7 +191,16 @@ static void ast2400_realize(DeviceState *dev, Error 
> **errp)
>  sysbus_mmio_map(SYS_BUS_DEVICE(>spi), 1, AST2400_SPI_FLASH_BASE);
>  
>  /* SDMC - SDRAM Memory Controller */
> -object_property_set_bool(OBJECT(>sdmc), true, "realized", );
> +silicon_rev = (uint32_t)
> +object_property_get_int(OBJECT(>scu), "silicon-rev", );
> +if (err) {
> +error_propagate(errp, err);
> +return;
> +}
> +
> +object_property_set_int(OBJECT(>sdmc), silicon_rev, "silicon-rev", 
> );
> +object_property_set_bool(OBJECT(>sdmc), true, "realized", _err);
> +error_propagate(, local_err);
>  if (err) {
>  error_propagate(errp, err);
>  return;
> diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
> index 54e29a865d88..1ee13d578899 100644
> --- a/hw/arm/palmetto-bmc.c
> +++ b/hw/arm/palmetto-bmc.c
> @@ -74,6 +74,8 @@ static void palmetto_bmc_init(MachineState *machine)
> _abort);
>  object_property_set_int(OBJECT(>soc), 0x120CE416, "hw-strap1",
>  _abort);
> +object_property_set_int(OBJECT(>soc), AST2400_A0_SILICON_REV,
> +"silicon-rev", _abort);
>  object_property_set_bool(OBJECT(>soc), true, "realized",
>   _abort);
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 7/7] ast2400: add a memory controller device model

2016-07-05 Thread Andrew Jeffery
On Mon, 2016-07-04 at 14:18 +0200, Cédric Le Goater wrote:
> The uboot in the previous release of the SDK was using a hardcoded
> value for memory size. This is not true anymore, the value is now
> retrieved from the memory controller.
> 
> Below is a model for this device, only supporting unlock and
> configuration. Without it, we endup running a guest with 64MB, which
> is a bit low for Linux nowdays.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/arm/ast2400.c  |  13 +
>  hw/misc/Makefile.objs |   2 +-
>  hw/misc/aspeed_sdmc.c | 126 
> ++
>  include/hw/arm/ast2400.h  |   1 +
>  include/hw/misc/aspeed_sdmc.h |  49 
>  5 files changed, 190 insertions(+), 1 deletion(-)
>  create mode 100644 hw/misc/aspeed_sdmc.c
>  create mode 100644 include/hw/misc/aspeed_sdmc.h
> 
> diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
> index 9c30b45f87a9..fb0156ba8bc1 100644
> --- a/hw/arm/ast2400.c
> +++ b/hw/arm/ast2400.c
> @@ -27,6 +27,7 @@
>  #define AST2400_FMC_BASE 0X1E62
>  #define AST2400_SPI_BASE 0X1E63
>  #define AST2400_VIC_BASE 0x1E6C
> +#define AST2400_SDMC_BASE0x1E6E
>  #define AST2400_SCU_BASE 0x1E6E2000
>  #define AST2400_TIMER_BASE   0x1E782000
>  #define AST2400_I2C_BASE 0x1E78A000
> @@ -99,6 +100,10 @@ static void ast2400_init(Object *obj)
>  object_initialize(>spi, sizeof(s->spi), "aspeed.smc.spi");
>  object_property_add_child(obj, "spi", OBJECT(>spi), NULL);
>  qdev_set_parent_bus(DEVICE(>spi), sysbus_get_default());
> +
> +object_initialize(>sdmc, sizeof(s->sdmc), TYPE_ASPEED_SDMC);
> +object_property_add_child(obj, "sdmc", OBJECT(>sdmc), NULL);
> +qdev_set_parent_bus(DEVICE(>sdmc), sysbus_get_default());
>  }
>  
>  static void ast2400_realize(DeviceState *dev, Error **errp)
> @@ -184,6 +189,14 @@ static void ast2400_realize(DeviceState *dev, Error 
> **errp)
>  }
>  sysbus_mmio_map(SYS_BUS_DEVICE(>spi), 0, AST2400_SPI_BASE);
>  sysbus_mmio_map(SYS_BUS_DEVICE(>spi), 1, AST2400_SPI_FLASH_BASE);
> +
> +/* SDMC - SDRAM Memory Controller */
> +object_property_set_bool(OBJECT(>sdmc), true, "realized", );
> +if (err) {
> +error_propagate(errp, err);
> +return;
> +}
> +sysbus_mmio_map(SYS_BUS_DEVICE(>sdmc), 0, AST2400_SDMC_BASE);
>  }
>  
>  static void ast2400_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index 54020aa06c00..d488b748c789 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -52,4 +52,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
>  obj-$(CONFIG_EDU) += edu.o
>  obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
>  obj-$(CONFIG_AUX) += aux.o
> -obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
> +obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
> new file mode 100644
> index ..52b6393b3f0b
> --- /dev/null
> +++ b/hw/misc/aspeed_sdmc.c
> @@ -0,0 +1,126 @@
> +/*
> + * ASPEED SDRAM Memory Controller
> + *
> + * Copyright 2016 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 "hw/misc/aspeed_sdmc.h"
> +#include "hw/qdev-properties.h"
> +#include "qapi/error.h"
> +#include "trace.h"

We need to #include "qemu/log.h" here to avoid build failures when
alternative tracing backends are enabled. I have forgotten it a couple
of times recently.

> +
> +/* Protection Key Register */
> +#define R_PROT(0x00 / 4)
> +#define   PROT_KEY_UNLOCK 0xFC600309
> +
> +/* Configuration Register */
> +#define R_CONF(0x04 / 4)
> +
> +static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
> +{
> +AspeedSDMCState *s = ASPEED_SDMC(opaque);
> +
> +addr >>= 2;
> +
> +if (addr >= ARRAY_SIZE(s->regs)) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx 
> "\n",
> +  __func__, addr);
> +return 0;
> +}
> +
> +return s->regs[addr];
> +}
> +
> +static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
> + unsigned int size)
> +{
> +AspeedSDMCState *s = ASPEED_SDMC(opaque);
> +
> +addr >>= 2;
> +
> +if (addr >= ARRAY_SIZE(s->regs)) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx 
> "\n",
> +  __func__, addr);
> +return;
> +}
> +
> +if (addr != R_PROT && s->regs[R_PROT] != PROT_KEY_UNLOCK) {
> +qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
> +return;
> +}
> +
> +s->regs[addr] = data;
> +}
> +
> +static const MemoryRegionOps aspeed_sdmc_ops = {
> +

Re: [Qemu-devel] [PATCH] misc/aspeed_scu: Fix build error caused by missing header

2016-06-27 Thread Andrew Jeffery
On Mon, 2016-06-27 at 17:53 -0400, Pranith Kumar wrote:
> Tracing configurations error out currently as follows:
> 
> /home/travis/build/pranith/qemu/hw/misc/aspeed_scu.c: In function 
> ‘aspeed_scu_read’:
> /home/travis/build/pranith/qemu/hw/misc/aspeed_scu.c:130:9: error: implicit 
> declaration of function ‘qemu_log_mask’ 
> [-Werror=implicit-function-declaration]
> /home/travis/build/pranith/qemu/hw/misc/aspeed_scu.c:130:9: error: nested 
> extern declaration of ‘qemu_log_mask’ [-Werror=nested-externs]
> /home/travis/build/pranith/qemu/hw/misc/aspeed_scu.c:130:23: error: 
> ‘LOG_GUEST_ERROR’ undeclared (first use in this function)
> /home/travis/build/pranith/qemu/hw/misc/aspeed_scu.c:130:23: note: each 
> undeclared identifier is reported only once for each function it appears in
> /home/travis/build/pranith/qemu/hw/misc/aspeed_scu.c: In function 
> ‘aspeed_scu_write’:
> /home/travis/build/pranith/qemu/hw/misc/aspeed_scu.c:154:23: error: 
> ‘LOG_GUEST_ERROR’ undeclared (first use in this function)
> 
> This is caused by a missing header file. Fix it.
> 
> Signed-off-by: Pranith Kumar <bobby.pr...@gmail.com>

Reviewed-by: Andrew Jeffery <and...@aj.id.au>

Thanks for the fix. I've enabled travis on my github repo now,
hopefully I'll catch this kind of issue before I send patches out. I
need to look into why I didn't trigger this issue in my own
change/build/test cycles.

Cheers,

Andrew

> ---
>  hw/misc/aspeed_scu.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> index 4f9df58..23f5175 100644
> --- a/hw/misc/aspeed_scu.c
> +++ b/hw/misc/aspeed_scu.c
> @@ -15,6 +15,7 @@
>  #include "qapi/error.h"
>  #include "qapi/visitor.h"
>  #include "qemu/bitops.h"
> +#include "qemu/log.h"
>  #include "trace.h"
>  
>  #define TO_REG(offset) ((offset) >> 2)

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v3 0/3] Add ASPEED SCU device

2016-06-27 Thread Andrew Jeffery
On Mon, 2016-06-27 at 14:47 +0100, Peter Maydell wrote:
> On 24 June 2016 at 05:58, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > Hi all,
> > 
> > These are three patches implementing minimal functionality for the ASPEED 
> > System
> > Control Unit device and integrating it into the AST2400 SoC 
> > model/palmetto-bmc
> > machine. The device is critical for initialisation of u-boot and the kernel 
> > as
> > it provides chip level control registers, influencing the configuration of 
> > the
> > software and the software's configuration of the SoC.
> > 
> > Since v2:
> > 
> > * Fix mixing of offsets and register indexes
> > * Sanity check device property values
> > * SoC actually initialises the silicon revision
> > 
> > Since v1:
> > 
> > * Select reset values based on silicon revision
> > * Expose hardware strapping values via properties
> > 
> > Andrew Jeffery (3):
> >   hw/misc: Add a model for the ASPEED System Control Unit
> >   ast2400: Integrate the SCU model and set silicon revision
> >   palmetto-bmc: Configure the SCU's hardware strapping register
> 
> 
> Applied to target-arm.next, thanks.

Thanks; I intend to send a follow-up patch addressing the discussion on
patch 3/3. I'm away for a week so it will miss soft-freeze, but given
the nature of the patch that might not be the end of the world?

Cheers,

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v3 1/3] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-27 Thread Andrew Jeffery
On Mon, 2016-06-27 at 14:42 +0100, Peter Maydell wrote:
> On 24 June 2016 at 05:58, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > The SCU is a collection of chip-level control registers that manage the
> > various functions supported by ASPEED SoCs. Typically the bits control
> > interactions with clocks, external hardware or reset behaviour, and we
> > can largly take a hands-off approach to reads and writes.
> > 
> > Firmware makes heavy use of the state to determine how to boot, but the
> > reset values vary from SoC to SoC (eg AST2400 vs AST2500). A qdev
> > property is exposed so that the integrating SoC model can configure the
> > silicon revision, which in-turn selects the appropriate reset values.
> > Further qdev properties are exposed so the board model can configure the
> > board-dependent hardware strapping.
> > 
> > Almost all provided AST2400 reset values are specified by the datasheet.
> > The notable exception is SOC_SCRATCH1, where we mark the DRAM as
> > successfully initialised to avoid unnecessary dark corners in the SoC's
> > u-boot support.
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > ---
> > Since v2:
> > 
> > * Fix mixing of offsets and register indexes
> > * Sanity check device property values
> > * Move trace event definition to hw/misc/trace-events
> > 
> > Since v1:
> > 
> > * Move reset values into SCU implementation (also make register defines 
> > private)
> > * Expose silicon-rev property which is used to select appropriate reset 
> > values
> > * Expose hw-strap1/hw-strap2 properties for board-specific SoC configuration
> > 
> >  hw/misc/Makefile.objs|   1 +
> >  hw/misc/aspeed_scu.c | 284 
> > +++
> >  hw/misc/trace-events |   3 +
> >  include/hw/misc/aspeed_scu.h |  34 ++
> >  4 files changed, 322 insertions(+)
> >  create mode 100644 hw/misc/aspeed_scu.c
> >  create mode 100644 include/hw/misc/aspeed_scu.h
> > 
> > diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> > index ffb49c11aca6..54020aa06c00 100644
> > --- a/hw/misc/Makefile.objs
> > +++ b/hw/misc/Makefile.objs
> > @@ -52,3 +52,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
> >  obj-$(CONFIG_EDU) += edu.o
> >  obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
> >  obj-$(CONFIG_AUX) += aux.o
> > +obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
> > diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> > new file mode 100644
> > index ..ff231dbb3c17
> > --- /dev/null
> > +++ b/hw/misc/aspeed_scu.c
> > @@ -0,0 +1,284 @@
> > +/*
> > + * ASPEED System Control Unit
> > + *
> > + * Andrew Jeffery <and...@aj.id.au>
> > + *
> > + * Copyright 2016 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 
> osdep.h provides this, you don't need to include it yourself.
> 
> Otherwise
> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
> 
> so if this is the only problem with the series I'll fix it up
> when I put it in target-arm.next.
> 

As far as I'm aware that's the only issue aside from the discussion on
patch 3/3.

Cheers,

Andrew

signature.asc
Description: This is a digitally signed message part


[Qemu-devel] [PATCH v3 3/3] palmetto-bmc: Configure the SCU's hardware strapping register

2016-06-23 Thread Andrew Jeffery
The magic constant configures the following options:

* 28:27: Configure DRAM size as 256MB
* 26:24: DDR3 SDRAM with CL = 6, CWL = 5
* 23: Configure 24/48MHz CLKIN
* 22: Disable GPIOE pass-through mode
* 21: Disable GPIOD pass-through mode
* 20: Enable LPC decode of SuperIO 0x2E/0x4E addresses
* 19: Disable ACPI
* 18: Configure 48MHz CLKIN
* 17: Disable BMC 2nd boot watchdog timer
* 16: Decode SuperIO address 0x2E
* 15: VGA Class Code
* 14: Enable LPC dedicated reset pin
* 13:12: Enable SPI Master and SPI Slave to AHB Bridge
* 11:10: Select CPU:AHB ratio = 2:1
* 9:8: Select 384MHz H-PLL
* 7: Configure MAC#2 for RMII/NCSI
* 6: Configure MAC#1 for RMII/NCSI
* 5: No VGA BIOS ROM
* 4: Boot using 32bit SPI address mode
* 3:2: Select 16MB VGA memory
* 1:0: Boot from SPI flash memory

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
Reviewed-by: Cédric Le Goater <c...@kaod.org>
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
---
 hw/arm/palmetto-bmc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
index a51d960510ee..b8eed21348d8 100644
--- a/hw/arm/palmetto-bmc.c
+++ b/hw/arm/palmetto-bmc.c
@@ -44,6 +44,8 @@ static void palmetto_bmc_init(MachineState *machine)
 >ram);
 object_property_add_const_link(OBJECT(>soc), "ram", OBJECT(>ram),
_abort);
+object_property_set_int(OBJECT(>soc), 0x120CE416, "hw-strap1",
+_abort);
 object_property_set_bool(OBJECT(>soc), true, "realized",
  _abort);
 
-- 
2.7.4




[Qemu-devel] [PATCH v3 1/3] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-23 Thread Andrew Jeffery
The SCU is a collection of chip-level control registers that manage the
various functions supported by ASPEED SoCs. Typically the bits control
interactions with clocks, external hardware or reset behaviour, and we
can largly take a hands-off approach to reads and writes.

Firmware makes heavy use of the state to determine how to boot, but the
reset values vary from SoC to SoC (eg AST2400 vs AST2500). A qdev
property is exposed so that the integrating SoC model can configure the
silicon revision, which in-turn selects the appropriate reset values.
Further qdev properties are exposed so the board model can configure the
board-dependent hardware strapping.

Almost all provided AST2400 reset values are specified by the datasheet.
The notable exception is SOC_SCRATCH1, where we mark the DRAM as
successfully initialised to avoid unnecessary dark corners in the SoC's
u-boot support.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v2:

* Fix mixing of offsets and register indexes
* Sanity check device property values
* Move trace event definition to hw/misc/trace-events

Since v1:

* Move reset values into SCU implementation (also make register defines private)
* Expose silicon-rev property which is used to select appropriate reset values
* Expose hw-strap1/hw-strap2 properties for board-specific SoC configuration

 hw/misc/Makefile.objs|   1 +
 hw/misc/aspeed_scu.c | 284 +++
 hw/misc/trace-events |   3 +
 include/hw/misc/aspeed_scu.h |  34 ++
 4 files changed, 322 insertions(+)
 create mode 100644 hw/misc/aspeed_scu.c
 create mode 100644 include/hw/misc/aspeed_scu.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ffb49c11aca6..54020aa06c00 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -52,3 +52,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += aux.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
new file mode 100644
index ..ff231dbb3c17
--- /dev/null
+++ b/hw/misc/aspeed_scu.c
@@ -0,0 +1,284 @@
+/*
+ * ASPEED System Control Unit
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2016 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 
+#include "hw/misc/aspeed_scu.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qemu/bitops.h"
+#include "trace.h"
+
+#define TO_REG(offset) ((offset) >> 2)
+
+#define PROT_KEY TO_REG(0x00)
+#define SYS_RST_CTRL TO_REG(0x04)
+#define CLK_SEL  TO_REG(0x08)
+#define CLK_STOP_CTRLTO_REG(0x0C)
+#define FREQ_CNTR_CTRL   TO_REG(0x10)
+#define FREQ_CNTR_EVAL   TO_REG(0x14)
+#define IRQ_CTRL TO_REG(0x18)
+#define D2PLL_PARAM  TO_REG(0x1C)
+#define MPLL_PARAM   TO_REG(0x20)
+#define HPLL_PARAM   TO_REG(0x24)
+#define FREQ_CNTR_RANGE  TO_REG(0x28)
+#define MISC_CTRL1   TO_REG(0x2C)
+#define PCI_CTRL1TO_REG(0x30)
+#define PCI_CTRL2TO_REG(0x34)
+#define PCI_CTRL3TO_REG(0x38)
+#define SYS_RST_STATUS   TO_REG(0x3C)
+#define SOC_SCRATCH1 TO_REG(0x40)
+#define SOC_SCRATCH2 TO_REG(0x44)
+#define MAC_CLK_DELAYTO_REG(0x48)
+#define MISC_CTRL2   TO_REG(0x4C)
+#define VGA_SCRATCH1 TO_REG(0x50)
+#define VGA_SCRATCH2 TO_REG(0x54)
+#define VGA_SCRATCH3 TO_REG(0x58)
+#define VGA_SCRATCH4 TO_REG(0x5C)
+#define VGA_SCRATCH5 TO_REG(0x60)
+#define VGA_SCRATCH6 TO_REG(0x64)
+#define VGA_SCRATCH7 TO_REG(0x68)
+#define VGA_SCRATCH8 TO_REG(0x6C)
+#define HW_STRAP1TO_REG(0x70)
+#define RNG_CTRL TO_REG(0x74)
+#define RNG_DATA TO_REG(0x78)
+#define SILICON_REV  TO_REG(0x7C)
+#define PINMUX_CTRL1 TO_REG(0x80)
+#define PINMUX_CTRL2 TO_REG(0x84)
+#define PINMUX_CTRL3 TO_REG(0x88)
+#define PINMUX_CTRL4 TO_REG(0x8C)
+#define PINMUX_CTRL5 TO_REG(0x90)
+#define PINMUX_CTRL6 TO_REG(0x94)
+#define WDT_RST_CTRL TO_REG(0x9C)
+#define PINMUX_CTRL7 TO_REG(0xA0)
+#define PINMUX_CTRL8 TO_REG(0xA4)
+#define PINMUX_CTRL9 TO_REG(0xA8)
+#define WAKEUP_ENTO_REG(0xC0)
+#define WAKEUP_CTRL  TO_REG(0xC4)
+#define HW_STRAP2TO_REG(0xD0)
+#define FREE_CNTR4   TO_REG(0xE0)
+#define FREE_CNTR4_EXT   TO_REG(0xE4)
+#define CPU2_CTRLTO_REG(0x100)
+#define CPU2_BASE_SEG1   TO_REG(0x104)
+#define CPU2_BASE_SEG2   TO_REG(0x108)
+#define CPU2_BASE_SEG3   TO_REG(0x10C)
+#define CPU2_BASE_SEG4   TO_REG(0x110

[Qemu-devel] [PATCH v3 2/3] ast2400: Integrate the SCU model and set silicon revision

2016-06-23 Thread Andrew Jeffery
By specifying the silicon revision we select the appropriate reset
values for the SoC.

Additionally, expose hardware strapping properties aliasing those
provided by the SCU for board-specific configuration.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
Reviewed-by: Cédric Le Goater <c...@kaod.org>
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>
---
Since v2:

* Configure SoC silicon revision in the SCU via silicon-rev property

Since v1:

* Remove reset value configuration
* Alias the SCU's hardware strapping properties to expose them to boards

 hw/arm/ast2400.c | 21 +
 include/hw/arm/ast2400.h |  2 ++
 2 files changed, 23 insertions(+)

diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
index 4a9de0e10cbc..b14a82fcdef1 100644
--- a/hw/arm/ast2400.c
+++ b/hw/arm/ast2400.c
@@ -24,9 +24,12 @@
 #define AST2400_IOMEM_SIZE   0x0020
 #define AST2400_IOMEM_BASE   0x1E60
 #define AST2400_VIC_BASE 0x1E6C
+#define AST2400_SCU_BASE 0x1E6E2000
 #define AST2400_TIMER_BASE   0x1E782000
 #define AST2400_I2C_BASE 0x1E78A000
 
+#define AST2400_A0_SILICON_REV   0x02000303
+
 static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
 static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
 
@@ -72,6 +75,16 @@ static void ast2400_init(Object *obj)
 object_initialize(>i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
 object_property_add_child(obj, "i2c", OBJECT(>i2c), NULL);
 qdev_set_parent_bus(DEVICE(>i2c), sysbus_get_default());
+
+object_initialize(>scu, sizeof(s->scu), TYPE_ASPEED_SCU);
+object_property_add_child(obj, "scu", OBJECT(>scu), NULL);
+qdev_set_parent_bus(DEVICE(>scu), sysbus_get_default());
+qdev_prop_set_uint32(DEVICE(>scu), "silicon-rev",
+ AST2400_A0_SILICON_REV);
+object_property_add_alias(obj, "hw-strap1", OBJECT(>scu),
+  "hw-strap1", _abort);
+object_property_add_alias(obj, "hw-strap2", OBJECT(>scu),
+  "hw-strap2", _abort);
 }
 
 static void ast2400_realize(DeviceState *dev, Error **errp)
@@ -110,6 +123,14 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>timerctrl), i, irq);
 }
 
+/* SCU */
+object_property_set_bool(OBJECT(>scu), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>scu), 0, AST2400_SCU_BASE);
+
 /* UART - attach an 8250 to the IO space as our UART5 */
 if (serial_hds[0]) {
 qemu_irq uart5 = qdev_get_gpio_in(DEVICE(>vic), uart_irqs[4]);
diff --git a/include/hw/arm/ast2400.h b/include/hw/arm/ast2400.h
index c05ed5376736..f1a64fd3893d 100644
--- a/include/hw/arm/ast2400.h
+++ b/include/hw/arm/ast2400.h
@@ -14,6 +14,7 @@
 
 #include "hw/arm/arm.h"
 #include "hw/intc/aspeed_vic.h"
+#include "hw/misc/aspeed_scu.h"
 #include "hw/timer/aspeed_timer.h"
 #include "hw/i2c/aspeed_i2c.h"
 
@@ -27,6 +28,7 @@ typedef struct AST2400State {
 AspeedVICState vic;
 AspeedTimerCtrlState timerctrl;
 AspeedI2CState i2c;
+AspeedSCUState scu;
 } AST2400State;
 
 #define TYPE_AST2400 "ast2400"
-- 
2.7.4




[Qemu-devel] [PATCH v3 0/3] Add ASPEED SCU device

2016-06-23 Thread Andrew Jeffery
Hi all,

These are three patches implementing minimal functionality for the ASPEED System
Control Unit device and integrating it into the AST2400 SoC model/palmetto-bmc
machine. The device is critical for initialisation of u-boot and the kernel as
it provides chip level control registers, influencing the configuration of the
software and the software's configuration of the SoC.

Since v2:

* Fix mixing of offsets and register indexes
* Sanity check device property values
* SoC actually initialises the silicon revision

Since v1:

* Select reset values based on silicon revision
* Expose hardware strapping values via properties

Andrew Jeffery (3):
  hw/misc: Add a model for the ASPEED System Control Unit
  ast2400: Integrate the SCU model and set silicon revision
  palmetto-bmc: Configure the SCU's hardware strapping register

 hw/arm/ast2400.c |  21 
 hw/arm/palmetto-bmc.c|   2 +
 hw/misc/Makefile.objs|   1 +
 hw/misc/aspeed_scu.c | 284 +++
 hw/misc/trace-events |   3 +
 include/hw/arm/ast2400.h |   2 +
 include/hw/misc/aspeed_scu.h |  34 ++
 7 files changed, 347 insertions(+)
 create mode 100644 hw/misc/aspeed_scu.c
 create mode 100644 include/hw/misc/aspeed_scu.h

-- 
2.7.4




Re: [Qemu-devel] [PATCH v2 3/3] palmetto-bmc: Configure the SCU's hardware strapping register

2016-06-23 Thread Andrew Jeffery
On Thu, 2016-06-23 at 18:39 +0100, Peter Maydell wrote:
> On 23 June 2016 at 03:15, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > The magic constant configures the following options:
> > 
> > * 28:27: Configure DRAM size as 256MB
> > * 26:24: DDR3 SDRAM with CL = 6, CWL = 5
> > * 23: Configure 24/48MHz CLKIN
> > * 22: Disable GPIOE pass-through mode
> > * 21: Disable GPIOD pass-through mode
> > * 20: Enable LPC decode of SuperIO 0x2E/0x4E addresses
> > * 19: Disable ACPI
> > * 18: Configure 48MHz CLKIN
> > * 17: Disable BMC 2nd boot watchdog timer
> > * 16: Decode SuperIO address 0x2E
> > * 15: VGA Class Code
> > * 14: Enable LPC dedicated reset pin
> > * 13:12: Enable SPI Master and SPI Slave to AHB Bridge
> > * 11:10: Select CPU:AHB ratio = 2:1
> > * 9:8: Select 384MHz H-PLL
> > * 7: Configure MAC#2 for RMII/NCSI
> > * 6: Configure MAC#1 for RMII/NCSI
> > * 5: No VGA BIOS ROM
> > * 4: Boot using 32bit SPI address mode
> > * 3:2: Select 16MB VGA memory
> > * 1:0: Boot from SPI flash memory
> Maybe we should say this in a comment in the code?

The list describes our specific value choices in the register's
bitfields rather than fully documenting the bitfields and values. If
you prefer I could switch to the latter and make it a comment, but
failing that my only thought was if we tweaked the value the comment
maybe come out of sync. By putting our choices in the commit message
the description is at least accurate for what was configured at the
time.

However I don't expect we will tweak the value...

> 
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > ---
> >  hw/arm/palmetto-bmc.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
> > index a51d960510ee..b8eed21348d8 100644
> > --- a/hw/arm/palmetto-bmc.c
> > +++ b/hw/arm/palmetto-bmc.c
> > @@ -44,6 +44,8 @@ static void palmetto_bmc_init(MachineState *machine)
> >  >ram);
> >  object_property_add_const_link(OBJECT(>soc), "ram", 
> > OBJECT(>ram),
> > _abort);
> > +object_property_set_int(OBJECT(>soc), 0x120CE416, "hw-strap1",
> > +_abort);
> >  object_property_set_bool(OBJECT(>soc), true, "realized",
> >   _abort);
> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>

Cheers,

Andrew


signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v2 1/3] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-23 Thread Andrew Jeffery
On Thu, 2016-06-23 at 18:42 +0100, Peter Maydell wrote:
> On 23 June 2016 at 03:15, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > The SCU is a collection of chip-level control registers that manage the
> > various functions supported by ASPEED SoCs. Typically the bits control
> > interactions with clocks, external hardware or reset behaviour, and we
> > can largly take a hands-off approach to reads and writes.
> > 
> > Firmware makes heavy use of the state to determine how to boot, but the
> > reset values vary from SoC to SoC (eg AST2400 vs AST2500). A qdev
> > property is exposed so that the integrating SoC model can configure the
> > silicon revision, which in-turn selects the appropriate reset values.
> > Further qdev properties are exposed so the board model can configure the
> > board-dependent hardware strapping.
> > 
> > Almost all provided AST2400 reset values are specified by the datasheet.
> > The notable exception is SOC_SCRATCH1, where we mark the DRAM as
> > successfully initialised to avoid unnecessary dark corners in the SoC's
> > u-boot support.
> > 
> > +static Property aspeed_scu_properties[] = {
> > +DEFINE_PROP_UINT32("silicon-rev", AspeedSCUState, silicon_rev, 0),
> > +DEFINE_PROP_UINT32("hw-strap1", AspeedSCUState, hw_strap1, 0),
> > +DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap1, 0),
> > +DEFINE_PROP_END_OF_LIST(),
> > +};
> You don't seem to specify in the board layer or the SoC layer
> any of these except hw-strap1, so should the default values
> for these really all be zero?

Both strap register default values are 0 according to the datasheet.

> 
> I suspect silicon-rev at least should either have a default
> value specified here, or have the SoC layer specify it.
> (It probably should not be specified at the board level.)

I intended to set silicon-rev in the SoC layer, so I'll fix patch 2/3.
With the addition of sanity checking in the SCU's realise() we'll catch
the case where it's an invalid value (eg 0). I don't think it's right
to plow ahead with an unexpected configuration if a chosen default
value doesn't match the SoC at hand.

Maybe I shouldn't send patches with a heavy head cold :/

Cheers,

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v2 1/3] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-23 Thread Andrew Jeffery
On Thu, 2016-06-23 at 18:37 +0100, Peter Maydell wrote:
> On 23 June 2016 at 03:15, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > The SCU is a collection of chip-level control registers that manage the
> > various functions supported by ASPEED SoCs. Typically the bits control
> > interactions with clocks, external hardware or reset behaviour, and we
> > can largly take a hands-off approach to reads and writes.
> > 
> > Firmware makes heavy use of the state to determine how to boot, but the
> > reset values vary from SoC to SoC (eg AST2400 vs AST2500). A qdev
> > property is exposed so that the integrating SoC model can configure the
> > silicon revision, which in-turn selects the appropriate reset values.
> > Further qdev properties are exposed so the board model can configure the
> > board-dependent hardware strapping.
> > 
> > Almost all provided AST2400 reset values are specified by the datasheet.
> > The notable exception is SOC_SCRATCH1, where we mark the DRAM as
> > successfully initialised to avoid unnecessary dark corners in the SoC's
> > u-boot support.
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> Thanks -- I think the interface to the board is much nicer now.
> I have a couple of comments below.
> 
> > 
> >  hw/misc/Makefile.objs|   1 +
> >  hw/misc/aspeed_scu.c | 258 
> > +++
> >  include/hw/misc/aspeed_scu.h |  34 ++
> >  trace-events |   3 +
> >  4 files changed, 296 insertions(+)
> >  create mode 100644 hw/misc/aspeed_scu.c
> >  create mode 100644 include/hw/misc/aspeed_scu.h
> > 
> > diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> > index ffb49c11aca6..54020aa06c00 100644
> > --- a/hw/misc/Makefile.objs
> > +++ b/hw/misc/Makefile.objs
> > @@ -52,3 +52,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
> >  obj-$(CONFIG_EDU) += edu.o
> >  obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
> >  obj-$(CONFIG_AUX) += aux.o
> > +obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
> > diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
> > new file mode 100644
> > index ..a714431c45c5
> > --- /dev/null
> > +++ b/hw/misc/aspeed_scu.c
> > @@ -0,0 +1,258 @@
> > +/*
> > + * ASPEED System Control Unit
> > + *
> > + * Andrew Jeffery <and...@aj.id.au>
> > + *
> > + * Copyright 2016 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 
> > +#include "hw/misc/aspeed_scu.h"
> > +#include "hw/qdev-properties.h"
> > +#include "qapi/error.h"
> > +#include "qapi/visitor.h"
> > +#include "qemu/bitops.h"
> > +#include "trace.h"
> > +
> > +#define TO_REG(offset) ((offset) >> 2)
> > +
> > +#define PROT_KEY TO_REG(0x00)
> > +#define SYS_RST_CTRL TO_REG(0x04)
> > +#define CLK_SEL  TO_REG(0x08)
> > +#define CLK_STOP_CTRLTO_REG(0x0C)
> > +#define FREQ_CNTR_CTRL   TO_REG(0x10)
> > +#define FREQ_CNTR_EVAL   TO_REG(0x14)
> > +#define IRQ_CTRL TO_REG(0x18)
> > +#define D2PLL_PARAM  TO_REG(0x1C)
> > +#define MPLL_PARAM   TO_REG(0x20)
> > +#define HPLL_PARAM   TO_REG(0x24)
> > +#define FREQ_CNTR_RANGE  TO_REG(0x28)
> > +#define MISC_CTRL1   TO_REG(0x2C)
> > +#define PCI_CTRL1TO_REG(0x30)
> > +#define PCI_CTRL2TO_REG(0x34)
> > +#define PCI_CTRL3TO_REG(0x38)
> > +#define SYS_RST_STATUS   TO_REG(0x3C)
> > +#define SOC_SCRATCH1 TO_REG(0x40)
> > +#define SOC_SCRATCH2 TO_REG(0x44)
> > +#define MAC_CLK_DELAYTO_REG(0x48)
> > +#define MISC_CTRL2   TO_REG(0x4C)
> > +#define VGA_SCRATCH1 TO_REG(0x50)
> > +#define VGA_SCRATCH2 TO_REG(0x54)
> > +#define VGA_SCRATCH3 TO_REG(0x58)
> > +#define VGA_SCRATCH4 TO_REG(0x5C)
> > +#define VGA_SCRATCH5 TO_REG(0x60)
> > +#define VGA_SCRATCH6 TO_REG(0x64)
> > +#define VGA_SCRATCH7 TO_REG(0x68)
> > +#define VGA_SCRATCH8 TO_REG(0x6C)
> > +#define HW_STRAP1TO_REG(0x70)
> > +#define RNG_CTRL TO_REG(0x74)
> > +#define RNG_DATA TO_REG(0x78)
> > +#define SILICON_REV  TO_REG(0x7C)
> > +#define PINMUX_CTRL1  

[Qemu-devel] [PATCH v2 3/3] palmetto-bmc: Configure the SCU's hardware strapping register

2016-06-22 Thread Andrew Jeffery
The magic constant configures the following options:

* 28:27: Configure DRAM size as 256MB
* 26:24: DDR3 SDRAM with CL = 6, CWL = 5
* 23: Configure 24/48MHz CLKIN
* 22: Disable GPIOE pass-through mode
* 21: Disable GPIOD pass-through mode
* 20: Enable LPC decode of SuperIO 0x2E/0x4E addresses
* 19: Disable ACPI
* 18: Configure 48MHz CLKIN
* 17: Disable BMC 2nd boot watchdog timer
* 16: Decode SuperIO address 0x2E
* 15: VGA Class Code
* 14: Enable LPC dedicated reset pin
* 13:12: Enable SPI Master and SPI Slave to AHB Bridge
* 11:10: Select CPU:AHB ratio = 2:1
* 9:8: Select 384MHz H-PLL
* 7: Configure MAC#2 for RMII/NCSI
* 6: Configure MAC#1 for RMII/NCSI
* 5: No VGA BIOS ROM
* 4: Boot using 32bit SPI address mode
* 3:2: Select 16MB VGA memory
* 1:0: Boot from SPI flash memory

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
 hw/arm/palmetto-bmc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
index a51d960510ee..b8eed21348d8 100644
--- a/hw/arm/palmetto-bmc.c
+++ b/hw/arm/palmetto-bmc.c
@@ -44,6 +44,8 @@ static void palmetto_bmc_init(MachineState *machine)
 >ram);
 object_property_add_const_link(OBJECT(>soc), "ram", OBJECT(>ram),
_abort);
+object_property_set_int(OBJECT(>soc), 0x120CE416, "hw-strap1",
+_abort);
 object_property_set_bool(OBJECT(>soc), true, "realized",
  _abort);
 
-- 
2.7.4




[Qemu-devel] [PATCH v2 2/3] ast2400: Integrate the SCU model and set silicon revision

2016-06-22 Thread Andrew Jeffery
By specifying the silicon revision we select the appropriate reset
values for the SoC.

Additionally, expose hardware strapping properties aliasing those
provided by the SCU for board-specific configuration.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---

Since v1:

* Remove reset value configuration
* Configure SoC silicon revision in the SCU via property
* Alias the SCU's hardware strapping properties to expose them to boards

 hw/arm/ast2400.c | 17 +
 include/hw/arm/ast2400.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
index 4a9de0e10cbc..1a26d74e695c 100644
--- a/hw/arm/ast2400.c
+++ b/hw/arm/ast2400.c
@@ -24,6 +24,7 @@
 #define AST2400_IOMEM_SIZE   0x0020
 #define AST2400_IOMEM_BASE   0x1E60
 #define AST2400_VIC_BASE 0x1E6C
+#define AST2400_SCU_BASE 0x1E6E2000
 #define AST2400_TIMER_BASE   0x1E782000
 #define AST2400_I2C_BASE 0x1E78A000
 
@@ -72,6 +73,14 @@ static void ast2400_init(Object *obj)
 object_initialize(>i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
 object_property_add_child(obj, "i2c", OBJECT(>i2c), NULL);
 qdev_set_parent_bus(DEVICE(>i2c), sysbus_get_default());
+
+object_initialize(>scu, sizeof(s->scu), TYPE_ASPEED_SCU);
+object_property_add_child(obj, "scu", OBJECT(>scu), NULL);
+qdev_set_parent_bus(DEVICE(>scu), sysbus_get_default());
+object_property_add_alias(obj, "hw-strap1", OBJECT(>scu),
+  "hw-strap1", _abort);
+object_property_add_alias(obj, "hw-strap2", OBJECT(>scu),
+  "hw-strap2", _abort);
 }
 
 static void ast2400_realize(DeviceState *dev, Error **errp)
@@ -110,6 +119,14 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>timerctrl), i, irq);
 }
 
+/* SCU */
+object_property_set_bool(OBJECT(>scu), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>scu), 0, AST2400_SCU_BASE);
+
 /* UART - attach an 8250 to the IO space as our UART5 */
 if (serial_hds[0]) {
 qemu_irq uart5 = qdev_get_gpio_in(DEVICE(>vic), uart_irqs[4]);
diff --git a/include/hw/arm/ast2400.h b/include/hw/arm/ast2400.h
index c05ed5376736..f1a64fd3893d 100644
--- a/include/hw/arm/ast2400.h
+++ b/include/hw/arm/ast2400.h
@@ -14,6 +14,7 @@
 
 #include "hw/arm/arm.h"
 #include "hw/intc/aspeed_vic.h"
+#include "hw/misc/aspeed_scu.h"
 #include "hw/timer/aspeed_timer.h"
 #include "hw/i2c/aspeed_i2c.h"
 
@@ -27,6 +28,7 @@ typedef struct AST2400State {
 AspeedVICState vic;
 AspeedTimerCtrlState timerctrl;
 AspeedI2CState i2c;
+AspeedSCUState scu;
 } AST2400State;
 
 #define TYPE_AST2400 "ast2400"
-- 
2.7.4




[Qemu-devel] [PATCH v2 1/3] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-22 Thread Andrew Jeffery
The SCU is a collection of chip-level control registers that manage the
various functions supported by ASPEED SoCs. Typically the bits control
interactions with clocks, external hardware or reset behaviour, and we
can largly take a hands-off approach to reads and writes.

Firmware makes heavy use of the state to determine how to boot, but the
reset values vary from SoC to SoC (eg AST2400 vs AST2500). A qdev
property is exposed so that the integrating SoC model can configure the
silicon revision, which in-turn selects the appropriate reset values.
Further qdev properties are exposed so the board model can configure the
board-dependent hardware strapping.

Almost all provided AST2400 reset values are specified by the datasheet.
The notable exception is SOC_SCRATCH1, where we mark the DRAM as
successfully initialised to avoid unnecessary dark corners in the SoC's
u-boot support.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---

Since v1:

* Move reset values into SCU implementation (also make register defines private)
* Expose silicon-rev property which is used to select appropriate reset values
* Expose hw-strap1/hw-strap2 properties for board-specific SoC configuration

 hw/misc/Makefile.objs|   1 +
 hw/misc/aspeed_scu.c | 258 +++
 include/hw/misc/aspeed_scu.h |  34 ++
 trace-events |   3 +
 4 files changed, 296 insertions(+)
 create mode 100644 hw/misc/aspeed_scu.c
 create mode 100644 include/hw/misc/aspeed_scu.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ffb49c11aca6..54020aa06c00 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -52,3 +52,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += aux.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
new file mode 100644
index ..a714431c45c5
--- /dev/null
+++ b/hw/misc/aspeed_scu.c
@@ -0,0 +1,258 @@
+/*
+ * ASPEED System Control Unit
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2016 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 
+#include "hw/misc/aspeed_scu.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qemu/bitops.h"
+#include "trace.h"
+
+#define TO_REG(offset) ((offset) >> 2)
+
+#define PROT_KEY TO_REG(0x00)
+#define SYS_RST_CTRL TO_REG(0x04)
+#define CLK_SEL  TO_REG(0x08)
+#define CLK_STOP_CTRLTO_REG(0x0C)
+#define FREQ_CNTR_CTRL   TO_REG(0x10)
+#define FREQ_CNTR_EVAL   TO_REG(0x14)
+#define IRQ_CTRL TO_REG(0x18)
+#define D2PLL_PARAM  TO_REG(0x1C)
+#define MPLL_PARAM   TO_REG(0x20)
+#define HPLL_PARAM   TO_REG(0x24)
+#define FREQ_CNTR_RANGE  TO_REG(0x28)
+#define MISC_CTRL1   TO_REG(0x2C)
+#define PCI_CTRL1TO_REG(0x30)
+#define PCI_CTRL2TO_REG(0x34)
+#define PCI_CTRL3TO_REG(0x38)
+#define SYS_RST_STATUS   TO_REG(0x3C)
+#define SOC_SCRATCH1 TO_REG(0x40)
+#define SOC_SCRATCH2 TO_REG(0x44)
+#define MAC_CLK_DELAYTO_REG(0x48)
+#define MISC_CTRL2   TO_REG(0x4C)
+#define VGA_SCRATCH1 TO_REG(0x50)
+#define VGA_SCRATCH2 TO_REG(0x54)
+#define VGA_SCRATCH3 TO_REG(0x58)
+#define VGA_SCRATCH4 TO_REG(0x5C)
+#define VGA_SCRATCH5 TO_REG(0x60)
+#define VGA_SCRATCH6 TO_REG(0x64)
+#define VGA_SCRATCH7 TO_REG(0x68)
+#define VGA_SCRATCH8 TO_REG(0x6C)
+#define HW_STRAP1TO_REG(0x70)
+#define RNG_CTRL TO_REG(0x74)
+#define RNG_DATA TO_REG(0x78)
+#define SILICON_REV  TO_REG(0x7C)
+#define PINMUX_CTRL1 TO_REG(0x80)
+#define PINMUX_CTRL2 TO_REG(0x84)
+#define PINMUX_CTRL3 TO_REG(0x88)
+#define PINMUX_CTRL4 TO_REG(0x8C)
+#define PINMUX_CTRL5 TO_REG(0x90)
+#define PINMUX_CTRL6 TO_REG(0x94)
+#define WDT_RST_CTRL TO_REG(0x9C)
+#define PINMUX_CTRL7 TO_REG(0xA0)
+#define PINMUX_CTRL8 TO_REG(0xA4)
+#define PINMUX_CTRL9 TO_REG(0xA8)
+#define WAKEUP_ENTO_REG(0xC0)
+#define WAKEUP_CTRL  TO_REG(0xC4)
+#define HW_STRAP2TO_REG(0xD0)
+#define FREE_CNTR4   TO_REG(0xE0)
+#define FREE_CNTR4_EXT   TO_REG(0xE4)
+#define CPU2_CTRLTO_REG(0x100)
+#define CPU2_BASE_SEG1   TO_REG(0x104)
+#define CPU2_BASE_SEG2   TO_REG(0x108)
+#define CPU2_BASE_SEG3   TO_REG(0x10C)
+#define CPU2_BASE_SEG4   TO_REG(0x110)
+#define CPU2_BASE_SEG5   TO_REG(0x114)
+#define CPU2_CACHE_CTRL  TO_REG(0x118)
+#define UART_HPLL_CLKTO_REG(0x160)
+#define

[Qemu-devel] [PATCH v2 0/3] Add ASPEED SCU device

2016-06-22 Thread Andrew Jeffery
Hi all,

These are three patches implementing minimal functionality for the ASPEED System
Control Unit device and integrating it into the AST2400 SoC model/palmetto-bmc
machine. The device is critical for initialisation of u-boot and the kernel as
it provides chip level control registers, influencing the configuration of the
software and the software's configuration of the SoC.

Since v1:

* Select reset values based on silicon ID
* Expose hardware strapping values via properties

Cheers,

Andrew

Andrew Jeffery (3):
  hw/misc: Add a model for the ASPEED System Control Unit
  ast2400: Integrate the SCU model and set silicon revision
  palmetto-bmc: Configure the SCU's hardware strapping register

 hw/arm/ast2400.c |  17 +++
 hw/arm/palmetto-bmc.c|   2 +
 hw/misc/Makefile.objs|   1 +
 hw/misc/aspeed_scu.c | 258 +++
 include/hw/arm/ast2400.h |   2 +
 include/hw/misc/aspeed_scu.h |  34 ++
 trace-events |   3 +
 7 files changed, 317 insertions(+)
 create mode 100644 hw/misc/aspeed_scu.c
 create mode 100644 include/hw/misc/aspeed_scu.h

-- 
2.7.4




Re: [Qemu-devel] [PATCH 1/2] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-21 Thread Andrew Jeffery
On Tue, 2016-06-21 at 07:56 +0100, Peter Maydell wrote:
> On 21 June 2016 at 04:49, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > On Mon, 2016-06-20 at 14:57 +0100, Peter Maydell wrote:
> > > 
> > > I think there are a couple of plausible ways you might model this:
> > > 
> > > (a) just have a single property for "revision" which corresponds
> > > to the revision of this bit of silicon IP within the SoC; the
> > > model of the device itself then knows what the reset state is
> > > for this revision of the device.
> > > (b) ditto, but also have some configurable flags where relevant
> > > (ie approximately where it's the same IP rev within the SoC
> > > but it's been configured by tying down different config lines;
> > > for instance hw/dma/pl330.c has a collection of properties
> > > which match the configurable knobs for the hardware.)
> > Okay. I think (b) is the most appropriate. The board-controllable bits
> > are primarily in the hardware strapping register. The register is
> > composed of fields of mostly unrelated bits, so we could go two ways
> > here:
> > 
> > (1) expose the register through a single 32bit property
> > (2) break out a property for each bitfield
> > 
> > Do you have a preference? grepping the tree suggests there isn't a
> > precedent for "large" numbers of properties* so maybe (2) is overkill,
> > but (1) feels like it might fit into the overly-general-interface
> > problem that we're trying to eliminate.
> > 
> > * Seems the microblaze CPU defines the most with 9 properties?
> (You forgot '-n' on your sort rune.)
> hw/dma/pl330.c has 15.

Ugh.

> 
> > 
> > Approach (2) will leave us with 21 properties for the SCU.
> What would the 21 properties be in this case?
> 
> But yes, a single 32 bit property would probably be better.

Alright, I'll go ahead with that.

Thanks for the feedback.

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 1/2] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-20 Thread Andrew Jeffery
On Mon, 2016-06-20 at 14:57 +0100, Peter Maydell wrote:
> On 20 June 2016 at 04:44, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > On Fri, 2016-06-17 at 15:22 +0100, Peter Maydell wrote:
> > > 
> > > +static Property aspeed_scu_properties[] = {
> > > +DEFINE_PROP_ARRAY("reset", AspeedSCUState, num_resets, reset,
> > > +  qdev_prop_uint32, uint32_t),
> > > +DEFINE_PROP_END_OF_LIST(),
> > > +};
> > > +
> > > +#define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
> > > This seems like a very unwieldy way of specifying the reset values
> > > for this device. Are they really all fully configurable in the
> > > hardware? It seems unlikely. I'd much rather see something that
> > > looks more like what you might plausibly be configuring when wiring
> > > up the SoC, which might be some version/revision numbers and/or
> > > some particular tweakable parameters.
> > Right. I left out some context which may clear things up: We are
> > working with two SoCs at the moment, the AST2400 and AST2500 (hopefully
> > the AST2500 patches will be sent to the list soon). I wanted to
> > abstract the configuration to cater for the differences in register
> > values between the SoCs, less so for wiring the one SoC up in a
> > different fashion. For what it's worth, out of 86 registers defined in
> > the IO space between the two SoCs, 37 take the same value and 49
> > differ.
> I think there are a couple of plausible ways you might model this:
> 
> (a) just have a single property for "revision" which corresponds
> to the revision of this bit of silicon IP within the SoC; the
> model of the device itself then knows what the reset state is
> for this revision of the device.
> (b) ditto, but also have some configurable flags where relevant
> (ie approximately where it's the same IP rev within the SoC
> but it's been configured by tying down different config lines;
> for instance hw/dma/pl330.c has a collection of properties
> which match the configurable knobs for the hardware.)

Okay. I think (b) is the most appropriate. The board-controllable bits
are primarily in the hardware strapping register. The register is
composed of fields of mostly unrelated bits, so we could go two ways
here:

(1) expose the register through a single 32bit property
(2) break out a property for each bitfield

Do you have a preference? grepping the tree suggests there isn't a
precedent for "large" numbers of properties* so maybe (2) is overkill,
but (1) feels like it might fit into the overly-general-interface
problem that we're trying to eliminate.

* Seems the microblaze CPU defines the most with 9 properties? Approach
(2) will leave us with 21 properties for the SCU.

$ git grep -c DEFINE_PROP | sort -t: -k2 -r | head -n1
target-microblaze/cpu.c:9

> 
> You might or might not have enough visibility into the thing to
> know which of these is closest to what the real hardware is doing;
> if not then it's a matter of taste, looking at what is varying
> between the two and what isn't, etc. But "board level specifies
> all the register reset values" is definitely far too broad
> and generalised an API, I think.
> 
> > 
> > Separately, the qdev array approach was lifted from your commit
> > 9c7d489379c2 hw/vexpress: Set reset values for daughterboard
> > oscillators.
> You'll notice that we only configure the specific things
> that need configuring with interfaces specific to those things
> (eg "daughterboard clocks" and "daughterboard voltages" are
> separate), not a single "have a complete set of register values" API.

Yes, I appreciate that now. Thanks.

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 1/2] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-19 Thread Andrew Jeffery
On Fri, 2016-06-17 at 15:22 +0100, Peter Maydell wrote:
On 16 June 2016 at 08:48, Andrew Jeffery <and...@aj.id.au> wrote:


The SCU is a collection of chip-level control registers that manage the
various functions supported by the AST2400. Typically the bits control
interactions with clocks, external hardware or reset behaviour, and we
can largly take a hands-off approach to reads and writes.


Firmware makes heavy use of the state to determine how to boot, but the
reset values vary from SoC to SoC. qdev properties are exposed so that
the integrating SoC model can configure the appropriate reset values.


Signed-off-by: Andrew Jeffery <and...@aj.id.au>
Reviewed-by: Cédric Le Goater <c...@kaod.org>
Reviewed-by: Joel Stanley <j...@jms.id.au>
---
+static Property aspeed_scu_properties[] = {
+DEFINE_PROP_ARRAY("reset", AspeedSCUState, num_resets, reset,
+  qdev_prop_uint32, uint32_t),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+#define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
This seems like a very unwieldy way of specifying the reset values
for this device. Are they really all fully configurable in the
hardware? It seems unlikely. I'd much rather see something that
looks more like what you might plausibly be configuring when wiring
up the SoC, which might be some version/revision numbers and/or
some particular tweakable parameters.

Right. I left out some context which may clear things up: We are
working with two SoCs at the moment, the AST2400 and AST2500 (hopefully
the AST2500 patches will be sent to the list soon). I wanted to
abstract the configuration to cater for the differences in register
values between the SoCs, less so for wiring the one SoC up in a
different fashion. For what it's worth, out of 86 registers defined in
the IO space between the two SoCs, 37 take the same value and 49
differ.

I can rework the commit message to say as much.

Separately, the qdev array approach was lifted from your commit
9c7d489379c2 hw/vexpress: Set reset values for daughterboard
oscillators. Another approach would be to set the members of the SCU's
reset array directly as we know the type. That seems less convoluted
but my gut instinct was that wasn't how we should be configuring the
devices. Is qdev the right way to go in the SCU's case?

Cheers,

Andrew

signature.asc
Description: This is a digitally signed message part


[Qemu-devel] [PATCH 0/2] Add ASPEED SCU device

2016-06-16 Thread Andrew Jeffery
Hi all,

These are two patches implementing minimal functionality for the ASPEED System
Control Unit device and integrating it into the AST2400 SoC model. The device is
critical for initialisation of u-boot and the kernel as it provides chip level
control registers, influencing the configuration of the software and the
software's configuration of the SoC.

Cheers,

Andrew

Andrew Jeffery (2):
  hw/misc: Add a model for the ASPEED System Control Unit
  ast2400: Integrate the SCU model and configure reset values

 hw/arm/ast2400.c |  57 +
 hw/misc/Makefile.objs|   1 +
 hw/misc/aspeed_scu.c | 147 +++
 include/hw/arm/ast2400.h |   2 +
 include/hw/misc/aspeed_scu.h | 108 +++
 trace-events |   3 +
 6 files changed, 318 insertions(+)
 create mode 100644 hw/misc/aspeed_scu.c
 create mode 100644 include/hw/misc/aspeed_scu.h

-- 
2.7.4




[Qemu-devel] [PATCH 2/2] ast2400: Integrate the SCU model and configure reset values

2016-06-16 Thread Andrew Jeffery
Almost all configured reset values are specified by the datasheet. The
notable exception is ASPEED_SCU_SOC_SCRATCH1, where we mark the DRAM as
successfully initialised by the SoC to avoid unnecessary dark corners in
the SoC's u-boot support.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
Reviewed-by: Cédric Le Goater <c...@kaod.org>
Reviewed-by: Joel Stanley <j...@jms.id.au>
---
 hw/arm/ast2400.c | 57 
 include/hw/arm/ast2400.h |  2 ++
 2 files changed, 59 insertions(+)

diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
index 4a9de0e10cbc..fc0da5c38557 100644
--- a/hw/arm/ast2400.c
+++ b/hw/arm/ast2400.c
@@ -24,12 +24,48 @@
 #define AST2400_IOMEM_SIZE   0x0020
 #define AST2400_IOMEM_BASE   0x1E60
 #define AST2400_VIC_BASE 0x1E6C
+#define AST2400_SCU_BASE 0x1E6E2000
 #define AST2400_TIMER_BASE   0x1E782000
 #define AST2400_I2C_BASE 0x1E78A000
 
 static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
 static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
 
+static const AspeedSCUResetCfg scu_reset[] = {
+/* Values are defaults from the datasheet except where noted */
+{ ASPEED_SCU_SYS_RST_CTRL,   0xFFCFFEDCU },
+{ ASPEED_SCU_CLK_SEL,0xF3F4U },
+{ ASPEED_SCU_CLK_STOP_CTRL,  0x19FC3E8BU },
+{ ASPEED_SCU_D2PLL_PARAM,0x00026108U },
+{ ASPEED_SCU_MPLL_PARAM, 0x00030291U },
+{ ASPEED_SCU_HPLL_PARAM, 0x0291U },
+{ ASPEED_SCU_MISC_CTRL1, 0x0010U },
+{ ASPEED_SCU_PCI_CTRL1,  0x20001A03U },
+{ ASPEED_SCU_PCI_CTRL2,  0x20001A03U },
+{ ASPEED_SCU_PCI_CTRL3,  0x0430U },
+{ ASPEED_SCU_SYS_RST_STATUS, 0x0001U },
+{ ASPEED_SCU_SOC_SCRATCH1,   0x00C0U }, /* SoC completed DRAM init */
+{ ASPEED_SCU_MISC_CTRL2, 0x0023U },
+{ ASPEED_SCU_HW_STRAP1,  0x120CE416U }, /* Extracted after boot */
+{ ASPEED_SCU_RNG_CTRL,   0x000EU },
+{ ASPEED_SCU_REV_ID, 0x02000303U },
+{ ASPEED_SCU_PINMUX_CTRL2,   0xF000U },
+{ ASPEED_SCU_PINMUX_CTRL3,   0x0100U },
+{ ASPEED_SCU_PINMUX_CTRL4,   0x00FFU },
+{ ASPEED_SCU_PINMUX_CTRL5,   0xA000U },
+{ ASPEED_SCU_WDT_RST_CTRL,   0x0033U },
+{ ASPEED_SCU_PINMUX_CTRL8,   0xU },
+{ ASPEED_SCU_PINMUX_CTRL9,   0x000FU },
+{ ASPEED_SCU_FREE_CNTR4, 0x00FFU },
+{ ASPEED_SCU_FREE_CNTR4_EXT, 0x00FFU },
+{ ASPEED_SCU_CPU2_BASE_SEG1, 0x8000U },
+{ ASPEED_SCU_CPU2_BASE_SEG4, 0x1E60U },
+{ ASPEED_SCU_CPU2_BASE_SEG5, 0xC000U },
+{ ASPEED_SCU_UART_HPLL_CLK,  0x1903U },
+{ ASPEED_SCU_PCIE_CTRL,  0x007BU },
+{ ASPEED_SCU_BMC_DEV_ID, 0x2402U }
+};
+
 /*
  * IO handlers: simply catch any reads/writes to IO addresses that aren't
  * handled by a device mapping.
@@ -57,6 +93,7 @@ static const MemoryRegionOps ast2400_io_ops = {
 
 static void ast2400_init(Object *obj)
 {
+int i;
 AST2400State *s = AST2400(obj);
 
 s->cpu = cpu_arm_init("arm926");
@@ -72,6 +109,18 @@ static void ast2400_init(Object *obj)
 object_initialize(>i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
 object_property_add_child(obj, "i2c", OBJECT(>i2c), NULL);
 qdev_set_parent_bus(DEVICE(>i2c), sysbus_get_default());
+
+object_initialize(>scu, sizeof(s->scu), TYPE_ASPEED_SCU);
+object_property_add_child(obj, "scu", OBJECT(>scu), NULL);
+qdev_set_parent_bus(DEVICE(>scu), sysbus_get_default());
+
+qdev_prop_set_uint32(DEVICE(>scu), "len-reset", ASPEED_SCU_NR_REGS);
+for (i = 0; i < ARRAY_SIZE(scu_reset); i++) {
+int reg = ASPEED_SCU_TO_REG(scu_reset[i].offset);
+char *propname = g_strdup_printf("reset[%d]", reg);
+qdev_prop_set_uint32(DEVICE(>scu), propname, scu_reset[i].val);
+g_free(propname);
+}
 }
 
 static void ast2400_realize(DeviceState *dev, Error **errp)
@@ -110,6 +159,14 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>timerctrl), i, irq);
 }
 
+/* SCU */
+object_property_set_bool(OBJECT(>scu), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>scu), 0, AST2400_SCU_BASE);
+
 /* UART - attach an 8250 to the IO space as our UART5 */
 if (serial_hds[0]) {
 qemu_irq uart5 = qdev_get_gpio_in(DEVICE(>vic), uart_irqs[4]);
diff --git a/include/hw/arm/ast2400.h b/include/hw/arm/ast2400.h
index c05ed5376736..f1a64fd3893d 100644
--- a/include/hw/arm/ast2400.h
+++ b/include/hw/arm/ast2400.h
@@ -14,6 +14,7 @@
 
 #include "hw/arm/arm.h"
 #include "hw/intc/aspeed_vic.h"
+#include "hw/misc/aspeed_scu.h"
 #include "hw/timer/aspeed_timer.h"
 #include "hw/i2c

[Qemu-devel] [PATCH 1/2] hw/misc: Add a model for the ASPEED System Control Unit

2016-06-16 Thread Andrew Jeffery
The SCU is a collection of chip-level control registers that manage the
various functions supported by the AST2400. Typically the bits control
interactions with clocks, external hardware or reset behaviour, and we
can largly take a hands-off approach to reads and writes.

Firmware makes heavy use of the state to determine how to boot, but the
reset values vary from SoC to SoC. qdev properties are exposed so that
the integrating SoC model can configure the appropriate reset values.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
Reviewed-by: Cédric Le Goater <c...@kaod.org>
Reviewed-by: Joel Stanley <j...@jms.id.au>
---
 hw/misc/Makefile.objs|   1 +
 hw/misc/aspeed_scu.c | 147 +++
 include/hw/misc/aspeed_scu.h | 108 +++
 trace-events |   3 +
 4 files changed, 259 insertions(+)
 create mode 100644 hw/misc/aspeed_scu.c
 create mode 100644 include/hw/misc/aspeed_scu.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ffb49c11aca6..54020aa06c00 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -52,3 +52,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += aux.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
new file mode 100644
index ..492cf82af425
--- /dev/null
+++ b/hw/misc/aspeed_scu.c
@@ -0,0 +1,147 @@
+/*
+ * ASPEED System Control Unit
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2016 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 
+#include "hw/misc/aspeed_scu.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qemu/bitops.h"
+#include "trace.h"
+
+#define SCU_KEY 0x1688A8A8
+#define SCU_IO_REGION_SIZE 0x2
+
+static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
+{
+AspeedSCUState *s = ASPEED_SCU(opaque);
+
+if (ASPEED_SCU_TO_REG(offset) >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+  __func__, offset);
+return 0;
+}
+
+switch (offset) {
+case ASPEED_SCU_WAKEUP_EN:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Read of write-only offset 0x%" HWADDR_PRIx "\n",
+  __func__, offset);
+break;
+}
+
+return s->regs[ASPEED_SCU_TO_REG(offset)];
+}
+
+static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
+ unsigned size)
+{
+AspeedSCUState *s = ASPEED_SCU(opaque);
+
+if (ASPEED_SCU_TO_REG(offset) >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+  __func__, offset);
+return;
+}
+
+if (offset > ASPEED_SCU_PROT_KEY && offset < ASPEED_SCU_CPU2_BASE_SEG1 &&
+s->regs[ASPEED_SCU_TO_REG(ASPEED_SCU_PROT_KEY)] != SCU_KEY) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
+return;
+}
+
+trace_aspeed_scu_write(offset, size, data);
+
+switch (offset) {
+case ASPEED_SCU_FREQ_CNTR_EVAL:
+case ASPEED_SCU_VGA_SCRATCH1 ... ASPEED_SCU_VGA_SCRATCH8:
+case ASPEED_SCU_RNG_DATA:
+case ASPEED_SCU_REV_ID:
+case ASPEED_SCU_FREE_CNTR4:
+case ASPEED_SCU_FREE_CNTR4_EXT:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
+  __func__, offset);
+return;
+}
+
+s->regs[ASPEED_SCU_TO_REG(offset)] = (uint32_t) data;
+}
+
+static const MemoryRegionOps aspeed_scu_ops = {
+.read = aspeed_scu_read,
+.write = aspeed_scu_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid.min_access_size = 4,
+.valid.max_access_size = 4,
+.valid.unaligned = false,
+};
+
+static void aspeed_scu_reset(DeviceState *dev)
+{
+AspeedSCUState *s = ASPEED_SCU(dev);
+
+memcpy(s->regs, s->reset, sizeof(s->regs));
+}
+
+static void aspeed_scu_realize(DeviceState *dev, Error **errp)
+{
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+AspeedSCUState *s = ASPEED_SCU(dev);
+
+memory_region_init_io(>iomem, OBJECT(s), _scu_ops, s,
+  TYPE_ASPEED_SCU, SCU_IO_REGION_SIZE);
+
+sysbus_init_mmio(sbd, >iomem);
+}
+
+static const VMStateDescription vmstate_aspeed_scu = {
+.name = "aspeed.new-vic",
+.version_id = 1,
+  

[Qemu-devel] [PATCH v2] hw/timer: Add value matching support to aspeed_timer

2016-06-15 Thread Andrew Jeffery
Value matching allows Linux to boot with CONFIG_NO_HZ_IDLE=y on the
palmetto-bmc machine. Two match registers are provided for each timer.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v1: Address comments from Peter

* Switch calculations to use muldiv64()
* Switch to loops when calculating the next event after wrap
* Bump VMStateDescription versions as required

 hw/timer/aspeed_timer.c | 138 +---
 include/hw/timer/aspeed_timer.h |   5 +-
 2 files changed, 104 insertions(+), 39 deletions(-)

diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
index 4b94808821b4..9b70ee09b07f 100644
--- a/hw/timer/aspeed_timer.c
+++ b/hw/timer/aspeed_timer.c
@@ -10,12 +10,10 @@
  */
 
 #include "qemu/osdep.h"
-#include "hw/ptimer.h"
 #include "hw/sysbus.h"
 #include "hw/timer/aspeed_timer.h"
 #include "qemu-common.h"
 #include "qemu/bitops.h"
-#include "qemu/main-loop.h"
 #include "qemu/timer.h"
 #include "qemu/log.h"
 #include "trace.h"
@@ -77,21 +75,96 @@ static inline bool timer_can_pulse(AspeedTimer *t)
 return t->id >= TIMER_FIRST_CAP_PULSE;
 }
 
+static inline bool timer_external_clock(AspeedTimer *t)
+{
+return timer_ctrl_status(t, op_external_clock);
+}
+
+static uint32_t clock_rates[] = { TIMER_CLOCK_APB_HZ, TIMER_CLOCK_EXT_HZ };
+
+static inline uint32_t calculate_rate(struct AspeedTimer *t)
+{
+return clock_rates[timer_external_clock(t)];
+}
+
+static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
+{
+uint64_t delta_ns = now_ns - MIN(now_ns, t->start);
+uint32_t rate = calculate_rate(t);
+uint64_t ticks = muldiv64(delta_ns, rate, NANOSECONDS_PER_SECOND);
+
+return t->reload - MIN(t->reload, ticks);
+}
+
+static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks)
+{
+uint64_t delta_ns;
+uint64_t delta_ticks;
+
+delta_ticks = t->reload - MIN(t->reload, ticks);
+delta_ns = muldiv64(delta_ticks, NANOSECONDS_PER_SECOND, 
calculate_rate(t));
+
+return t->start + delta_ns;
+}
+
+static uint64_t calculate_next(struct AspeedTimer *t)
+{
+uint64_t next = 0;
+uint32_t rate = calculate_rate(t);
+
+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 {
+reload_ns = muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate);
+t->start = now - ((now - t->start) % reload_ns);
+}
+}
+
+return next;
+}
+
 static void aspeed_timer_expire(void *opaque)
 {
 AspeedTimer *t = opaque;
+bool interrupt = false;
+uint32_t ticks;
 
-/* Only support interrupts on match values of zero for the moment - this is
- * sufficient to boot an aspeed_defconfig Linux kernel.
- *
- * TODO: matching on arbitrary values (see e.g. hw/timer/a9gtimer.c)
- */
-bool match = !(t->match[0] && t->match[1]);
-bool interrupt = timer_overflow_interrupt(t) || match;
-if (timer_enabled(t) && interrupt) {
+if (!timer_enabled(t)) {
+return;
+}
+
+ticks = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+
+if (!ticks) {
+interrupt = timer_overflow_interrupt(t) || !t->match[0] || 
!t->match[1];
+} else if (ticks <= MIN(t->match[0], t->match[1])) {
+interrupt = true;
+} else if (ticks <= MAX(t->match[0], t->match[1])) {
+interrupt = true;
+}
+
+if (interrupt) {
 t->level = !t->level;
 qemu_set_irq(t->irq, t->level);
 }
+
+timer_mod(>timer, calculate_next(t));
 }
 
 static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
@@ -100,7 +173,7 @@ static uint64_t aspeed_timer_get_value(AspeedTimer *t, int 
reg)
 
 switch (reg) {
 case TIMER_REG_STATUS:
-value = ptimer_get_count(t->timer);
+value = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 break;
 case TIMER_REG_RELOAD:
 value = t->reload;
@@ -160,24 +233,22 @@ static void aspeed_timer_set_value(AspeedTimerCtrlState 
*s, int timer, int reg,
 switch (reg) {
 case TIMER_REG_STATUS:
 if (timer_enabled(t)) {
-ptimer_set_count(t->

Re: [Qemu-devel] [PATCH] hw/timer: Add value matching support to aspeed_timer

2016-06-13 Thread Andrew Jeffery
On Fri, 2016-06-10 at 11:42 +0100, Peter Maydell wrote:
> On 10 June 2016 at 01:59, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > On Thu, 2016-06-09 at 19:15 +0100, Peter Maydell wrote:
> > > 
> > > On 27 May 2016 at 06:08, Andrew Jeffery <and...@aj.id.au> wrote:
> > > > 
> > > > 
> > > > Value matching allows Linux to boot with CONFIG_NO_HZ_IDLE=y on the
> > > > palmetto-bmc machine. Two match registers are provided for each timer.
> > > > 
> > > > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > > > ---
> > > > 
> > > > The change pulls out ptimer in favour of the regular timer 
> > > > infrastructure. As a
> > > > consequence it implements the conversions between ticks and time which 
> > > > feels a
> > > > little tedious. Any comments there would be appreciated.
> > > Couple of minor comments below.
> > > 
> > > > 
> > > > 
> > > >  hw/timer/aspeed_timer.c | 135 
> > > > ++--
> > > >  include/hw/timer/aspeed_timer.h |   6 +-
> > > >  2 files changed, 105 insertions(+), 36 deletions(-)
> > > > 
> > > > diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
> > > > index 4b94808821b4..905de0f788b2 100644
> > > > --- a/hw/timer/aspeed_timer.c
> > > > +++ b/hw/timer/aspeed_timer.c
> > > > @@ -9,13 +9,12 @@
> > > >   * the COPYING file in the top-level directory.
> > > >   */
> > > > 
> > > > +#include
> > > >  #include "qemu/osdep.h"
> > > osdep.h must always be the first include.
> > Thanks for picking that up.
> If you like you can run scripts/clean-includes file ...
> and it will automatically make any necessary changes like this to
> your files.

Thanks, I'll add that to my submission checklist

> 
> 
> > 
> > > 
> > > > 
> > > > +static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t 
> > > > now_ns)
> > > > +{
> > > > +uint64_t delta_ns = now_ns - MIN(now_ns, t->start);
> > > > +uint32_t ticks = (uint32_t) floor(delta_ns / calculate_period(t));
> > > Do we really need to do this with floating point ?
> > I went with floating point to avoid accumulating errors from truncation
> > by integer division. At eg 24MHz truncation increases the tick rate by
> > approximately 1 in 63. We're using floor() here, but that only
> > truncates at the end of the calculation, so the fractional current
> > tick.
> Right, but you only have a risk of truncation because of the way
> you've structured the calculation. You have
> 
> floor(delta_ns / calculate_period())
> == floor(delta_ns / (calculate_rate() / NS_PER_SEC))
> == floor((delta_ns * NS_PER_SEC) / calculate_rate())
> 
> and calculate_rate() returns either 100 or 2400.
> 
> So you have a 64 bit delta_ns, a 32 bit NANOSECONDS_PER_SECOND
> and a 32 bit frequency. We have a function for doing this
> accurately with integer arithmetic: muldiv64() (which takes
> a 64 bit a, 32 bit b and 32 bit c and returns (a*b)/c using
> an intermediate 96 bit precision to avoid overflow).
> 
> Doing ticks-to-ns and ns-to-ticks with muldiv64() is pretty
> standard (grep the codebase and you'll see a lot of it).

Right! As I didn't see a concern with floating point prior to sending
the patch I didn't try to rearrange the calculation. I'll rework to use
muldiv64().

> 
> > 
> > Having said that, grep'ing around under {,include/}hw/ doesn't show a
> > lot of use of floating point. It looks like we are explicitly avoiding
> > it, however with a quick search I didn't find it mentioned in any of
> > the docs. What's the reasoning? Should I use a fixed-point approach
> > like ptimer?
> My view is that hardware doesn't generally use floating point
> so it's odd to see it in a software model of hardware.

Fair enough.

>  Double
> doesn't actually get you any more bits than uint64_t anyway...
> 
> > 
> > > 
> > > > 
> > > > +return calculate_next(t);
> > 
> > > 
> > > Why is this recursing ?
> > The common case is that we return during iterating over seq array i.e.
> > we're anticipating another match event (either from the match values or
> > the timer reaching zero). If not then we've overrun, so we reinitialise
> > the timer by resetting the 'start' reference point then searching again
> > for the next event (i

Re: [Qemu-devel] [PATCH] hw/timer: Add value matching support to aspeed_timer

2016-06-09 Thread Andrew Jeffery
On Thu, 2016-06-09 at 19:15 +0100, Peter Maydell wrote:
> On 27 May 2016 at 06:08, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > Value matching allows Linux to boot with CONFIG_NO_HZ_IDLE=y on the
> > palmetto-bmc machine. Two match registers are provided for each timer.
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > ---
> > 
> > The change pulls out ptimer in favour of the regular timer infrastructure. 
> > As a
> > consequence it implements the conversions between ticks and time which 
> > feels a
> > little tedious. Any comments there would be appreciated.
> Couple of minor comments below.
> 
> > 
> >  hw/timer/aspeed_timer.c | 135 
> > ++--
> >  include/hw/timer/aspeed_timer.h |   6 +-
> >  2 files changed, 105 insertions(+), 36 deletions(-)
> > 
> > diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
> > index 4b94808821b4..905de0f788b2 100644
> > --- a/hw/timer/aspeed_timer.c
> > +++ b/hw/timer/aspeed_timer.c
> > @@ -9,13 +9,12 @@
> >   * the COPYING file in the top-level directory.
> >   */
> > 
> > +#include 
> >  #include "qemu/osdep.h"
> osdep.h must always be the first include.

Thanks for picking that up.

> 
> > 
> > -#include "hw/ptimer.h"
> >  #include "hw/sysbus.h"
> >  #include "hw/timer/aspeed_timer.h"
> >  #include "qemu-common.h"
> >  #include "qemu/bitops.h"
> > -#include "qemu/main-loop.h"
> >  #include "qemu/timer.h"
> >  #include "qemu/log.h"
> >  #include "trace.h"
> > @@ -77,21 +76,99 @@ static inline bool timer_can_pulse(AspeedTimer *t)
> >  return t->id >= TIMER_FIRST_CAP_PULSE;
> >  }
> > 
> > +static inline bool timer_external_clock(AspeedTimer *t)
> > +{
> > +return timer_ctrl_status(t, op_external_clock);
> > +}
> > +
> > +static double clock_rates[] = { TIMER_CLOCK_APB_HZ, TIMER_CLOCK_EXT_HZ };
> > +
> > +static inline double calculate_rate(struct AspeedTimer *t)
> > +{
> > +return clock_rates[timer_external_clock(t)];
> > +}
> > +
> > +static inline double calculate_period(struct AspeedTimer *t)
> > +{
> > +return NANOSECONDS_PER_SECOND / calculate_rate(t);
> > +}
> > +
> > +static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t 
> > now_ns)
> > +{
> > +uint64_t delta_ns = now_ns - MIN(now_ns, t->start);
> > +uint32_t ticks = (uint32_t) floor(delta_ns / calculate_period(t));
> Do we really need to do this with floating point ?

I went with floating point to avoid accumulating errors from truncation
by integer division. At eg 24MHz truncation increases the tick rate by
approximately 1 in 63. We're using floor() here, but that only
truncates at the end of the calculation, so the fractional current
tick.

Having said that, grep'ing around under {,include/}hw/ doesn't show a
lot of use of floating point. It looks like we are explicitly avoiding
it, however with a quick search I didn't find it mentioned in any of
the docs. What's the reasoning? Should I use a fixed-point approach
like ptimer?

> 
> > 
> > +
> > +return t->reload - MIN(t->reload, ticks);
> > +}
> > +
> > +static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t 
> > ticks)
> > +{
> > +uint64_t delta_ns;
> > +
> > +ticks = MIN(t->reload, ticks);
> > +delta_ns = (uint64_t) floor((t->reload - ticks) * calculate_period(t));
> > +
> > +return t->start + delta_ns;
> > +}
> > +
> > +static uint64_t calculate_next(struct AspeedTimer *t)
> > +{
> > +uint64_t now;
> > +uint64_t next;
> > +int i;
> > +/* 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[] = {
> > +MAX(t->match[0], t->match[1]),
> > +MIN(t->match[0], t->match[1]),
> > +0,
> > +};
> > +
> > +now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > +for (i = 0; i < ARRAY_SIZE(seq); i++) {
> > +next = calculate_time(t, seq[i]);
> > +if (now < next) {
> > +return next;
> > +}
> > +}
> > +
> > +{
> > +uint64_t reload_ns;
> > +
> > +reload_ns = (uint64_t) flo

Re: [Qemu-devel] [PATCH] hw/timer: Add value matching support to aspeed_timer

2016-06-07 Thread Andrew Jeffery
On Mon, 2016-06-06 at 15:01 +0100, Peter Maydell wrote:
> On 27 May 2016 at 06:08, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > Value matching allows Linux to boot with CONFIG_NO_HZ_IDLE=y on the
> > palmetto-bmc machine. Two match registers are provided for each timer.
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > ---
> > 
> > The change pulls out ptimer in favour of the regular timer infrastructure. 
> > As a
> > consequence it implements the conversions between ticks and time which 
> > feels a
> > little tedious. Any comments there would be appreciated.
> So what would you need from ptimer to be able to implement value
> matching with it; or is ptimer just too far away from what this
> timer device needs to make that worthwhile ?

I gave expanding the ptimer API some (quick) consideration. It feels
like it might be a departure from "simple" and depending on your view a
departure from "periodic"; though an interrupt for a given match value
is at least periodic with respect to itself. In this case the hardware
supports two match values, so if we add something to the ptimer API it
would need to support an arbitrary number of values
(ptimer_{add,del}_match(...)?). In this case the hardware counts down,
but just as we're doing currently we can fix the values to give the
right behaviour.

I guess the final thought was that you queried me on the #include
"qemu/main-loop.h" in the original patch, and that moving away from
ptimer would eliminate it.

If we come up with an acceptable match value API for ptimer I can
implement it and resend.

Cheers,

Andrew

signature.asc
Description: This is a digitally signed message part


[Qemu-devel] [PATCH] hw/timer: Add value matching support to aspeed_timer

2016-05-26 Thread Andrew Jeffery
Value matching allows Linux to boot with CONFIG_NO_HZ_IDLE=y on the
palmetto-bmc machine. Two match registers are provided for each timer.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---

The change pulls out ptimer in favour of the regular timer infrastructure. As a
consequence it implements the conversions between ticks and time which feels a
little tedious. Any comments there would be appreciated.

 hw/timer/aspeed_timer.c | 135 ++--
 include/hw/timer/aspeed_timer.h |   6 +-
 2 files changed, 105 insertions(+), 36 deletions(-)

diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
index 4b94808821b4..905de0f788b2 100644
--- a/hw/timer/aspeed_timer.c
+++ b/hw/timer/aspeed_timer.c
@@ -9,13 +9,12 @@
  * the COPYING file in the top-level directory.
  */
 
+#include 
 #include "qemu/osdep.h"
-#include "hw/ptimer.h"
 #include "hw/sysbus.h"
 #include "hw/timer/aspeed_timer.h"
 #include "qemu-common.h"
 #include "qemu/bitops.h"
-#include "qemu/main-loop.h"
 #include "qemu/timer.h"
 #include "qemu/log.h"
 #include "trace.h"
@@ -77,21 +76,99 @@ static inline bool timer_can_pulse(AspeedTimer *t)
 return t->id >= TIMER_FIRST_CAP_PULSE;
 }
 
+static inline bool timer_external_clock(AspeedTimer *t)
+{
+return timer_ctrl_status(t, op_external_clock);
+}
+
+static double clock_rates[] = { TIMER_CLOCK_APB_HZ, TIMER_CLOCK_EXT_HZ };
+
+static inline double calculate_rate(struct AspeedTimer *t)
+{
+return clock_rates[timer_external_clock(t)];
+}
+
+static inline double calculate_period(struct AspeedTimer *t)
+{
+return NANOSECONDS_PER_SECOND / calculate_rate(t);
+}
+
+static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
+{
+uint64_t delta_ns = now_ns - MIN(now_ns, t->start);
+uint32_t ticks = (uint32_t) floor(delta_ns / calculate_period(t));
+
+return t->reload - MIN(t->reload, ticks);
+}
+
+static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks)
+{
+uint64_t delta_ns;
+
+ticks = MIN(t->reload, ticks);
+delta_ns = (uint64_t) floor((t->reload - ticks) * calculate_period(t));
+
+return t->start + delta_ns;
+}
+
+static uint64_t calculate_next(struct AspeedTimer *t)
+{
+uint64_t now;
+uint64_t next;
+int i;
+/* 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[] = {
+MAX(t->match[0], t->match[1]),
+MIN(t->match[0], t->match[1]),
+0,
+};
+
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+for (i = 0; i < ARRAY_SIZE(seq); i++) {
+next = calculate_time(t, seq[i]);
+if (now < next) {
+return next;
+}
+}
+
+{
+uint64_t reload_ns;
+
+reload_ns = (uint64_t) floor(t->reload * calculate_period(t));
+t->start = now - ((now - t->start) % reload_ns);
+}
+
+return calculate_next(t);
+}
+
 static void aspeed_timer_expire(void *opaque)
 {
 AspeedTimer *t = opaque;
+bool interrupt = false;
+uint32_t ticks;
 
-/* Only support interrupts on match values of zero for the moment - this is
- * sufficient to boot an aspeed_defconfig Linux kernel.
- *
- * TODO: matching on arbitrary values (see e.g. hw/timer/a9gtimer.c)
- */
-bool match = !(t->match[0] && t->match[1]);
-bool interrupt = timer_overflow_interrupt(t) || match;
-if (timer_enabled(t) && interrupt) {
+if (!timer_enabled(t)) {
+return;
+}
+
+ticks = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+
+if (!ticks) {
+interrupt = timer_overflow_interrupt(t) || !t->match[0] || 
!t->match[1];
+} else if (ticks <= MIN(t->match[0], t->match[1])) {
+interrupt = true;
+} else if (ticks <= MAX(t->match[0], t->match[1])) {
+interrupt = true;
+}
+
+if (interrupt) {
 t->level = !t->level;
 qemu_set_irq(t->irq, t->level);
 }
+
+timer_mod(>timer, calculate_next(t));
 }
 
 static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
@@ -100,7 +177,7 @@ static uint64_t aspeed_timer_get_value(AspeedTimer *t, int 
reg)
 
 switch (reg) {
 case TIMER_REG_STATUS:
-value = ptimer_get_count(t->timer);
+value = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 break;
 case TIMER_REG_RELOAD:
 value = t->reload;
@@ -160,24 +237,21 @@ static void aspeed_timer_set_value(AspeedTimerCtrlState 
*s, int timer, int reg,
 switch (reg) {
 case TIMER_REG_STATUS:
 if (timer_enabled(t)) {
-ptimer_set_count(t->timer, value);
+uint64_t now 

Re: [Qemu-devel] [PATCH] i2c: add aspeed i2c crontroller

2016-05-23 Thread Andrew Jeffery
On Mon, 2016-05-23 at 07:55 +0200, Cédric Le Goater wrote:
> > 
> > The hunk fails to apply to master as the SCU isn't yet integrated
> > there. The change to ast2400.h also fails to apply for this reason.
> 
> Ah yes. I am using your branch for this patch. 
> 
> So, I will provide you a fix for "qemu/log.h" below  and let you do 
> the sending of the SCU device ? or do you want me to send it all ? 
> 

I'd make this patch apply to master and send it alone. The SCU patches
aren't quite ready for posting and I've got a few distractions at the
moment, so it might be a week or two before I can clean them up and
send them out. I'll apply them on top of the i2c controller patch when
I get around to it.

Cheers,

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH 2/4] hw/misc: add a TMP42{1, 2, 3} device model

2016-05-22 Thread Andrew Jeffery
Hi Cédric,

On Fri, 2016-05-20 at 18:31 +0200, Cédric Le Goater wrote:
> Largely inspired by the TMP105 temperature sensor, this patch brings
> to Qemu a model for TMP42{1,2,3} temperature sensors.
> 
> Specs can be found here :
> 
>   http://www.ti.com/lit/gpn/tmp421
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/misc/Makefile.objs |   1 +
>  hw/misc/tmp421.c  | 395 
> ++
>  2 files changed, 396 insertions(+)
>  create mode 100644 hw/misc/tmp421.c
> 
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index 1faf163c59f3..e50596965b03 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -1,6 +1,7 @@
>  common-obj-$(CONFIG_APPLESMC) += applesmc.o
>  common-obj-$(CONFIG_MAX111X) += max111x.o
>  common-obj-$(CONFIG_TMP105) += tmp105.o
> +common-obj-$(CONFIG_ASPEED_SOC) += tmp421.o
>  common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o
>  common-obj-$(CONFIG_SGA) += sga.o
>  common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
> diff --git a/hw/misc/tmp421.c b/hw/misc/tmp421.c
> new file mode 100644
> index ..e385ce053f5e
> --- /dev/null
> +++ b/hw/misc/tmp421.c
> @@ -0,0 +1,395 @@
> +/*
> + * Texas Instruments TMP421 temperature sensor.
> + *
> + * Copyright (c) 2016 IBM Corporation.
> + *
> + * Largely inspired by :
> + *
> + * Texas Instruments TMP105 temperature sensor.
> + *
> + * Copyright (C) 2008 Nokia Corporation
> + * Written by Andrzej Zaborowski 
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 or
> + * (at your option) version 3 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/hw.h"
> +#include "hw/i2c/i2c.h"
> +#include "qapi/error.h"
> +#include "qapi/visitor.h"
> +
> +/* Manufacturer / Device ID's */
> +#define TMP421_MANUFACTURER_ID  0x55
> +#define TMP421_DEVICE_ID0x21
> +#define TMP422_DEVICE_ID0x22
> +#define TMP423_DEVICE_ID0x23
> +
> +typedef struct DeviceInfo {
> +int model;
> +const char *name;
> +} DeviceInfo;
> +
> +static const DeviceInfo devices[] = {
> +{ TMP421_DEVICE_ID, "tmp421" },
> +{ TMP422_DEVICE_ID, "tmp422" },
> +{ TMP423_DEVICE_ID, "tmp423" },
> +};
> +
> +typedef struct TMP421State {
> +/*< private >*/
> +I2CSlave i2c;
> +/*< public >*/
> +
> +int16_t temperature[4];
> +
> +uint8_t status;
> +uint8_t config[2];
> +uint8_t rate;
> +
> +uint8_t len;

Given the starting point of the tmp105 code the patch looks okay, but I
was a bit thrown by the use of the 'len' member as what I'd consider an
index. For instance we reset len to zero in tmp421_event() after
populating buf, and then the data in buf is presumably sent out on a
recv transaction which again starts incrementing len. len is also
incremented when we don't interact with buf, e.g. when we instead
assign to pointer. It feels like it could be prone to bugs, and
'cb5ef3fa1871 tmp105: Fix I2C protocol bug' suggests that might not be
an unreasonable feeling.

But given the code already exists in tmp105 maybe it's fine?

Cheers,

Andrew

> +uint8_t buf[2];
> +uint8_t pointer;
> +
> +} TMP421State;
> +
> +typedef struct TMP421Class {
> +I2CSlaveClass parent_class;
> +DeviceInfo *dev;
> +} TMP421Class;
> +
> +#define TYPE_TMP421 "tmp421-generic"
> +#define TMP421(obj) OBJECT_CHECK(TMP421State, (obj), TYPE_TMP421)
> +
> +#define TMP421_CLASS(klass) \
> + OBJECT_CLASS_CHECK(TMP421Class, (klass), TYPE_TMP421)
> +#define TMP421_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(TMP421Class, (obj), TYPE_TMP421)
> +
> +/* the TMP421 registers */
> +#define TMP421_STATUS_REG   0x08
> +#defineTMP421_STATUS_BUSY (1 << 7)
> +#define TMP421_CONFIG_REG_1 0x09
> +#defineTMP421_CONFIG_RANGE(1 << 2)
> +#defineTMP421_CONFIG_SHUTDOWN (1 << 6)
> +#define TMP421_CONFIG_REG_2 0x0A
> +#defineTMP421_CONFIG_RC   (1 << 2)
> +#defineTMP421_CONFIG_LEN  (1 << 3)
> +#defineTMP421_CONFIG_REN  (1 << 4)
> +#defineTMP421_CONFIG_REN2 (1 << 5)
> +#defineTMP421_CONFIG_REN3 (1 << 6)
> +
> +#define TMP421_CONVERSION_RATE_REG  0x0B
> +#define TMP421_ONE_SHOT 0x0F
> +
> +#define TMP421_RESET0xFC
> +#define TMP421_MANUFACTURER_ID_REG 

Re: [Qemu-devel] [PATCH] i2c: add aspeed i2c crontroller

2016-05-22 Thread Andrew Jeffery
Hi Cédric,

On Fri, 2016-05-20 at 18:27 +0200, Cédric Le Goater wrote:
> The Aspeed AST2400 integrates a set of 14 I2C/SMBus bus controllers
> directly connected to ab APB bus which can be programmed as a master
> or slave.
> 
> This patch offers a device model for the master mode only, slave mode
> is not supported.
> 
> On the TODO list, we also have :
> 
>  - improve and harden the state machine. 
>  - bus recovery support (used by the Linux driver).
>  - transfer mode state machine bits. this is not strictly necessary as
>    it is mostly used for debug. The bus busy bit is deducted from the
>    I2C core engine of qemu.
>  - support of the pool buffer: 2048 bytes of internal SRAM (not used
>    by the Linux driver).
> 
> Signed-off-by: Cédric Le Goater <c...@kaod.org>
> ---
>  hw/arm/ast2400.c|  16 ++
>  hw/i2c/Makefile.objs|   1 +
>  hw/i2c/aspeed_i2c.c | 449 
> 
>  include/hw/arm/ast2400.h|   2 +
>  include/hw/i2c/aspeed_i2c.h |  62 ++
>  5 files changed, 530 insertions(+)
>  create mode 100644 hw/i2c/aspeed_i2c.c
>  create mode 100644 include/hw/i2c/aspeed_i2c.h
> 
> diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
> index cf9f37e6a301..4576e67cd483 100644
> --- a/hw/arm/ast2400.c
> +++ b/hw/arm/ast2400.c
> @@ -18,6 +18,7 @@
>  #include "hw/arm/ast2400.h"
>  #include "hw/char/serial.h"
>  #include "hw/boards.h"
> +#include "hw/i2c/aspeed_i2c.h"
>  
>  #define AST2400_UART_5_BASE  0x00184000
>  #define AST2400_IOMEM_SIZE   0x0020
> @@ -25,6 +26,7 @@
>  #define AST2400_VIC_BASE 0x1E6C
>  #define AST2400_SCU_BASE 0x1E6E2000
>  #define AST2400_TIMER_BASE   0x1E782000
> +#define AST2400_I2C_BASE 0x1E78A000
>  
>  static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
>  static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
> @@ -71,6 +73,10 @@ static void ast2400_init(Object *obj)
>  object_initialize(>scu, sizeof(s->scu), TYPE_ASPEED_SCU);
>  object_property_add_child(obj, "scu", OBJECT(>scu), NULL);
>  qdev_set_parent_bus(DEVICE(>scu), sysbus_get_default());

The hunk fails to apply to master as the SCU isn't yet integrated
there. The change to ast2400.h also fails to apply for this reason.

> +
> +object_initialize(>i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
> +object_property_add_child(obj, "i2c", OBJECT(>i2c), NULL);
> +qdev_set_parent_bus(DEVICE(>i2c), sysbus_get_default());
>  }
>  
>  static void ast2400_realize(DeviceState *dev, Error **errp)
> @@ -143,6 +149,16 @@ static void ast2400_realize(DeviceState *dev, Error 
> **errp)
>  serial_mm_init(>iomem, AST2400_UART_5_BASE, 2,
> uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
>  }
> +
> +/* I2C */
> +object_property_set_bool(OBJECT(>i2c), true, "realized", );
> +if (err) {
> +error_propagate(errp, err);
> +return;
> +}
> +sysbus_mmio_map(SYS_BUS_DEVICE(>i2c), 0, AST2400_I2C_BASE);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>i2c), 0,
> +   qdev_get_gpio_in(DEVICE(>vic), 12));
>  }
>  
>  static void ast2400_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
> index aeb8f38d70f1..1fd54edf4c23 100644
> --- a/hw/i2c/Makefile.objs
> +++ b/hw/i2c/Makefile.objs
> @@ -5,4 +5,5 @@ common-obj-$(CONFIG_APM) += pm_smbus.o
>  common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
>  common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
>  common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
> +common-obj-$(CONFIG_ASPEED_SOC) += aspeed_i2c.o
>  obj-$(CONFIG_OMAP) += omap_i2c.o
> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
> new file mode 100644
> index ..c56780d7e362
> --- /dev/null
> +++ b/hw/i2c/aspeed_i2c.c
> @@ -0,0 +1,449 @@
> +/*
> + * ARM Aspeed I2C controller
> + *
> + * Copyright (C) 2016 IBM Corp.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * a

[Qemu-devel] [PATCH v5 1/4] hw/timer: Add ASPEED timer device model

2016-03-15 Thread Andrew Jeffery
Implement basic ASPEED timer functionality for the AST2400 SoC[1]: Up to
8 timers can independently be configured, enabled, reset and disabled.
Some hardware features are not implemented, namely clock value matching
and pulse generation, but the implementation is enough to boot the Linux
kernel configured with aspeed_defconfig.

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v4:
  * Fix to compile when using GCC 4.x
  * Drop unnecessary asserts

Since v3:
  * Drop unnecessary mention of VMStateDescription in timer_to_ctrl description
  * Mention hw/timer/a9gtimer.c with respect to clock value matching
  * Add missing VMSTATE_END_OF_LIST() to vmstate_aspeed_timer_state

Since v2:
  * Improve handling of timer configuration with respect to enabled state
  * Remove redundant enabled member from AspeedTimer
  * Implement VMStateDescriptions
  * Fix interrupt behaviour (edge triggered, both edges)
  * Fix various issues with trace-event declarations
  * Include qemu/osdep.h

Since v1:
  * Refactor initialisation of and respect requested clock rates (APB/External)
  * Simplify some index calculations
  * Use tracing infrastructure instead of internal DPRINTF
  * Enforce access size constraints and alignment in MemoryRegionOps

 default-configs/arm-softmmu.mak |   1 +
 hw/timer/Makefile.objs  |   1 +
 hw/timer/aspeed_timer.c | 449 
 include/hw/timer/aspeed_timer.h |  59 ++
 trace-events|   9 +
 5 files changed, 519 insertions(+)
 create mode 100644 hw/timer/aspeed_timer.c
 create mode 100644 include/hw/timer/aspeed_timer.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a9f82a1..2bcd236 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -110,3 +110,4 @@ CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_ACPI=y
 CONFIG_SMBIOS=y
+CONFIG_ASPEED_SOC=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 5cfea6e..003c14f 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -32,3 +32,4 @@ obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
 
 common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
+common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
new file mode 100644
index 000..51e8303
--- /dev/null
+++ b/hw/timer/aspeed_timer.c
@@ -0,0 +1,449 @@
+/*
+ * ASPEED AST2400 Timer
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright (C) 2016 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 "hw/ptimer.h"
+#include "hw/sysbus.h"
+#include "hw/timer/aspeed_timer.h"
+#include "qemu-common.h"
+#include "qemu/bitops.h"
+#include "qemu/main-loop.h"
+#include "qemu/timer.h"
+#include "trace.h"
+
+#define TIMER_NR_REGS 4
+
+#define TIMER_CTRL_BITS 4
+#define TIMER_CTRL_MASK ((1 << TIMER_CTRL_BITS) - 1)
+
+#define TIMER_CLOCK_USE_EXT true
+#define TIMER_CLOCK_EXT_HZ 100
+#define TIMER_CLOCK_USE_APB false
+#define TIMER_CLOCK_APB_HZ 2400
+
+#define TIMER_REG_STATUS 0
+#define TIMER_REG_RELOAD 1
+#define TIMER_REG_MATCH_FIRST 2
+#define TIMER_REG_MATCH_SECOND 3
+
+#define TIMER_FIRST_CAP_PULSE 4
+
+enum timer_ctrl_op {
+op_enable = 0,
+op_external_clock,
+op_overflow_interrupt,
+op_pulse_enable
+};
+
+/**
+ * Avoid mutual references between AspeedTimerCtrlState and AspeedTimer
+ * structs, as it's a waste of memory. The ptimer BH callback needs to know
+ * whether a specific AspeedTimer is enabled, but this information is held in
+ * AspeedTimerCtrlState. So, provide a helper to hoist ourselves from an
+ * arbitrary AspeedTimer to AspeedTimerCtrlState.
+ */
+static inline AspeedTimerCtrlState *timer_to_ctrl(AspeedTimer *t)
+{
+const AspeedTimer (*timers)[] = (void *)t - (t->id * sizeof(*t));
+return container_of(timers, AspeedTimerCtrlState, timers);
+}
+
+static inline bool timer_ctrl_status(AspeedTimer *t, enum timer_ctrl_op op)
+{
+return !!(timer_to_ctrl(t)->ctrl & BIT(t->id * TIMER_CTRL_BITS + op));
+}
+
+static inline bool timer_enabled(AspeedTimer *t)
+{
+return timer_ctrl_status(t, op_enable);
+}
+
+static inline bool timer_overflow_interrupt(AspeedTimer *t)
+{
+return timer_ctrl_status(t, op_overflow_interrupt);
+}
+
+static inline bool timer_can_pulse(AspeedTimer *t)
+{
+return t->id >= TIMER_FIRST_CAP_PULSE;
+}
+
+static void aspeed_timer_expire(void *opaque)
+{
+AspeedTimer *t = opaque;
+
+/* Only support interrupts on match values of zero for the moment - this is
+ * sufficient to boot an aspeed_defconfig Linux kernel.
+ *
+ * TODO: matching o

[Qemu-devel] [PATCH v5 4/4] hw/arm: Add palmetto-bmc machine

2016-03-15 Thread Andrew Jeffery
The new machine is a thin layer over the AST2400 ARM926-based SoC[1].
Between the minimal machine and the current SoC implementation there is
enough functionality to boot an aspeed_defconfig Linux kernel to
userspace. Nothing yet is specific to the Palmetto's BMC (other than
using an AST2400 SoC), but creating specific machine types is preferable
to a generic machine that doesn't match any particular hardware.

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v4:
  * Rename to hw/arm/palmetto-bmc.c, update functions, structs and strings

Since v3:
  * Split the machine from the SoC implementation

Since v2:
  * Implement a SOC model to move code out from the machine definition
  * Rework the machine to better use QOM
  * Include qemu/osdep.h
  * Revert back to qemu_log_mask(LOG_UNIMP, ...) in IO handlers

 hw/arm/Makefile.objs  |  2 +-
 hw/arm/palmetto-bmc.c | 65 +++
 2 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/palmetto-bmc.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index f333b7f..954c9fe 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -16,4 +16,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
-obj-$(CONFIG_ASPEED_SOC) += ast2400.o
+obj-$(CONFIG_ASPEED_SOC) += ast2400.o palmetto-bmc.o
diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
new file mode 100644
index 000..55d7419
--- /dev/null
+++ b/hw/arm/palmetto-bmc.c
@@ -0,0 +1,65 @@
+/*
+ * OpenPOWER Palmetto BMC
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2016 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 "exec/address-spaces.h"
+#include "hw/arm/arm.h"
+#include "hw/arm/ast2400.h"
+#include "hw/boards.h"
+
+static struct arm_boot_info palmetto_bmc_binfo = {
+.loader_start = AST2400_SDRAM_BASE,
+.board_id = 0,
+.nb_cpus = 1,
+};
+
+typedef struct PalmettoBMCState {
+AST2400State soc;
+MemoryRegion ram;
+} PalmettoBMCState;
+
+static void palmetto_bmc_init(MachineState *machine)
+{
+PalmettoBMCState *bmc;
+
+bmc = g_new0(PalmettoBMCState, 1);
+object_initialize(>soc, (sizeof(bmc->soc)), TYPE_AST2400);
+object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
+  _abort);
+
+memory_region_allocate_system_memory(>ram, NULL, "ram", ram_size);
+memory_region_add_subregion(get_system_memory(), AST2400_SDRAM_BASE,
+>ram);
+object_property_add_const_link(OBJECT(>soc), "ram", OBJECT(>ram),
+   _abort);
+object_property_set_bool(OBJECT(>soc), true, "realized",
+ _abort);
+
+palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
+palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
+palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
+palmetto_bmc_binfo.ram_size = ram_size;
+arm_load_kernel(ARM_CPU(first_cpu), _bmc_binfo);
+}
+
+static void palmetto_bmc_machine_init(MachineClass *mc)
+{
+mc->desc = "OpenPOWER Palmetto BMC";
+mc->init = palmetto_bmc_init;
+mc->max_cpus = 1;
+mc->no_sdcard = 1;
+mc->no_floppy = 1;
+mc->no_cdrom = 1;
+mc->no_sdcard = 1;
+mc->no_parallel = 1;
+}
+
+DEFINE_MACHINE("palmetto-bmc", palmetto_bmc_machine_init);
-- 
2.5.0




[Qemu-devel] [PATCH v5 0/4] Add ASPEED AST2400 SoC and Palmetto BMC machine

2016-03-15 Thread Andrew Jeffery
This patch series models enough of the ASPEED AST2400 ARM9 SoC[0] to boot an
aspeed_defconfig Linux kernel[1][2]. Specifically, the series implements the
ASPEED timer and VIC devices, integrates them into an AST2400 SoC and exposes
it all through a new palmetto-bmc machine. The device model patches only
partially implement the hardware features of the timer and VIC, again mostly
just enough to boot Linux.

Unfortunately the datasheet describing the devices is not generally available,
but I'll try to add comments to any unclear areas.

The addition of the AST2400 to QEMU is motivated by use of the SoC as a BMC in
OpenPOWER[2][3] machines and the ongoing development of OpenBMC[4]. The
presence of a machine model utilising the AST2400 will help with development
and testing of the OpenBMC stack.

Cheers,

Andrew

[0] http://www.aspeedtech.com/products.php?fPath=20=376
[1] https://github.com/openbmc/linux/tree/dev-4.3
[2] git fetch g...@github.com:openbmc/linux.git dev-4.3
[3] http://openpowerfoundation.org/
[4] https://github.com/open-power/
[5] https://github.com/openbmc/openbmc

Changes since v4:

  * Switch approach to modelling a specific machine type (palmetto-bmc)
rather than something generic that may have no corresponding hardware
implementation
  * Address review comments from Jeremy Kerr, Cédric Le Goater, Dmitry Osipenko

Changes since v3:

  Address comments from Peter Maydell, splitting the machine model from
  hw/arm/ast2400.c into hw/arm/opbmc2400.c amongst other minor cleanups to the
  timer and VIC.

Changes since v2:

  This re-roll is a reasonable rework of the patches in the series, which may
  make it difficult to compare v1 to v2.

  Addressed reviews/comments from:
  * Peter Maydell
  * Alexey Kardashevskiy
  * Joel Stanley

Changes since v1:

  Addressed reviews/comments from:
  * Cédric Le Goater

Andrew Jeffery (4):
  hw/timer: Add ASPEED timer device model
  hw/intc: Add (new) ASPEED VIC device model
  hw/arm: Add ASPEED AST2400 SoC model
  hw/arm: Add palmetto-bmc machine

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/ast2400.c| 137 
 hw/arm/palmetto-bmc.c   |  65 ++
 hw/intc/Makefile.objs   |   1 +
 hw/intc/aspeed_vic.c| 339 ++
 hw/timer/Makefile.objs  |   1 +
 hw/timer/aspeed_timer.c | 449 
 include/hw/arm/ast2400.h|  35 
 include/hw/intc/aspeed_vic.h|  48 +
 include/hw/timer/aspeed_timer.h |  59 ++
 trace-events|  16 ++
 12 files changed, 1152 insertions(+)
 create mode 100644 hw/arm/ast2400.c
 create mode 100644 hw/arm/palmetto-bmc.c
 create mode 100644 hw/intc/aspeed_vic.c
 create mode 100644 hw/timer/aspeed_timer.c
 create mode 100644 include/hw/arm/ast2400.h
 create mode 100644 include/hw/intc/aspeed_vic.h
 create mode 100644 include/hw/timer/aspeed_timer.h

-- 
2.5.0




[Qemu-devel] [PATCH v5 3/4] hw/arm: Add ASPEED AST2400 SoC model

2016-03-15 Thread Andrew Jeffery
While the ASPEED AST2400 SoC[1] has a broad range of capabilities this
implementation is minimal, comprising an ARM926 processor, ASPEED VIC
and timer devices, and a 8250 UART.

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v3:

  * Split the SoC from the machine implementation

Since v2:
  * Implement a SOC model to move code out from the machine definition
  * Rework the machine to better use QOM
  * Include qemu/osdep.h
  * Revert back to qemu_log_mask(LOG_UNIMP, ...) in IO handlers

 hw/arm/Makefile.objs |   1 +
 hw/arm/ast2400.c | 137 +++
 include/hw/arm/ast2400.h |  35 
 3 files changed, 173 insertions(+)
 create mode 100644 hw/arm/ast2400.c
 create mode 100644 include/hw/arm/ast2400.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index a711e4d..f333b7f 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -16,3 +16,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
+obj-$(CONFIG_ASPEED_SOC) += ast2400.o
diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
new file mode 100644
index 000..daa5518
--- /dev/null
+++ b/hw/arm/ast2400.c
@@ -0,0 +1,137 @@
+/*
+ * AST2400 SoC
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ * Jeremy Kerr <j...@ozlabs.org>
+ *
+ * Copyright 2016 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 "exec/address-spaces.h"
+#include "hw/arm/ast2400.h"
+#include "hw/char/serial.h"
+
+#define AST2400_UART_5_BASE  0x00184000
+#define AST2400_IOMEM_SIZE   0x0020
+#define AST2400_IOMEM_BASE   0x1E60
+#define AST2400_VIC_BASE 0x1E6C
+#define AST2400_TIMER_BASE   0x1E782000
+
+static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
+static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
+
+/*
+ * IO handlers: simply catch any reads/writes to IO addresses that aren't
+ * handled by a device mapping.
+ */
+
+static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
+  __func__, offset, size);
+return 0;
+}
+
+static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t value,
+unsigned size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
+  __func__, offset, value, size);
+}
+
+static const MemoryRegionOps ast2400_io_ops = {
+.read = ast2400_io_read,
+.write = ast2400_io_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void ast2400_init(Object *obj)
+{
+AST2400State *s = AST2400(obj);
+
+s->cpu = cpu_arm_init("arm926");
+
+object_initialize(>vic, sizeof(s->vic), TYPE_ASPEED_VIC);
+object_property_add_child(obj, "vic", OBJECT(>vic), NULL);
+qdev_set_parent_bus(DEVICE(>vic), sysbus_get_default());
+
+object_initialize(>timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
+object_property_add_child(obj, "timerctrl", OBJECT(>timerctrl), NULL);
+qdev_set_parent_bus(DEVICE(>timerctrl), sysbus_get_default());
+}
+
+static void ast2400_realize(DeviceState *dev, Error **errp)
+{
+int i;
+AST2400State *s = AST2400(dev);
+Error *err = NULL;
+
+/* IO space */
+memory_region_init_io(>iomem, NULL, _io_ops, NULL,
+"ast2400.io", AST2400_IOMEM_SIZE);
+memory_region_add_subregion_overlap(get_system_memory(), 
AST2400_IOMEM_BASE,
+>iomem, -1);
+
+/* VIC */
+object_property_set_bool(OBJECT(>vic), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>vic), 0, AST2400_VIC_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(>vic), 0,
+   qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
+sysbus_connect_irq(SYS_BUS_DEVICE(>vic), 1,
+   qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
+
+/* Timer */
+object_property_set_bool(OBJECT(>timerctrl), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>timerctrl), 0, AST2400_TIMER_BASE);
+for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
+qemu_irq irq = qdev_get_gpio_in(DEVICE(>vic), timer_irqs[i]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>timerctrl), i, irq);
+}
+
+/* UART - attach an 8250 to the IO space as our UART5 */
+if (serial_hds[0]) {
+qemu_irq uart

[Qemu-devel] [PATCH v5 2/4] hw/intc: Add (new) ASPEED VIC device model

2016-03-15 Thread Andrew Jeffery
Implement a basic ASPEED VIC device model for the AST2400 SoC[1], with
enough functionality to boot an aspeed_defconfig Linux kernel. The model
implements the 'new' (revised) register set: While the hardware exposes
both the new and legacy register sets, accesses to the model's legacy
register set will not be serviced (however the access will be logged).

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v3:
  * Switch from g_assert() to qemu_log_mask(LOG_GUEST_ERROR, ...) in guest path

Since v2:
  * Implement all supported interrupt types and configurations
  * Implement a VMStateDescription
  * Log accesses to legacy IO space
  * Add documentation on some implementation and hardware details
  * Switch to extract64/deposit64 where possible
  * Drop int_ prefix from some struct member names
  * Fix various issues with trace-event declarations
  * Include qemu/osdep.h

 hw/intc/Makefile.objs|   1 +
 hw/intc/aspeed_vic.c | 339 +++
 include/hw/intc/aspeed_vic.h |  48 ++
 trace-events |   7 +
 4 files changed, 395 insertions(+)
 create mode 100644 hw/intc/aspeed_vic.c
 create mode 100644 include/hw/intc/aspeed_vic.h

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 6a13a39..0e47f0f 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -31,3 +31,4 @@ obj-$(CONFIG_XICS_KVM) += xics_kvm.o
 obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
 obj-$(CONFIG_S390_FLIC) += s390_flic.o
 obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c
new file mode 100644
index 000..19a0ff7
--- /dev/null
+++ b/hw/intc/aspeed_vic.c
@@ -0,0 +1,339 @@
+/*
+ * ASPEED Interrupt Controller (New)
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2015, 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+/* The hardware exposes two register sets, a legacy set and a 'new' set. The
+ * model implements the 'new' register set, and logs warnings on accesses to
+ * the legacy IO space.
+ *
+ * The hardware uses 32bit registers to manage 51 IRQs, with low and high
+ * registers for each conceptual register. The device model's implementation
+ * uses 64bit data types to store both low and high register values (in the one
+ * member), but must cope with access offset values in multiples of 4 passed to
+ * the callbacks. As such the read() and write() implementations process the
+ * provided offset to understand whether the access is requesting the lower or
+ * upper 32 bits of the 64bit member.
+ *
+ * Additionally, the "Interrupt Enable", "Edge Status" and "Software Interrupt"
+ * fields have separate "enable"/"status" and "clear" registers, where set bits
+ * are written to one or the other to change state (avoiding a
+ * read-modify-write sequence).
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "hw/intc/aspeed_vic.h"
+#include "qemu/bitops.h"
+#include "trace.h"
+
+#define AVIC_NEW_BASE_OFFSET 0x80
+
+#define AVIC_L_MASK 0xU
+#define AVIC_H_MASK 0x0007U
+#define AVIC_EVENT_W_MASK (0x78000ULL << 32)
+
+static void aspeed_vic_update(AspeedVICState *s)
+{
+uint64_t new = (s->raw & s->enable);
+uint64_t flags;
+
+flags = new & s->select;
+trace_aspeed_vic_update_fiq(!!flags);
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->select;
+trace_aspeed_vic_update_irq(!!flags);
+qemu_set_irq(s->irq, !!flags);
+}
+
+static void aspeed_vic_set_irq(void *opaque, int irq, int level)
+{
+uint64_t irq_mask;
+bool raise;
+AspeedVICState *s = (AspeedVICState *)opaque;
+
+if (irq > ASPEED_VIC_NR_IRQS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+  __func__, irq);
+return;
+}
+
+trace_aspeed_vic_set_irq(irq, level);
+
+irq_mask = BIT(irq);
+if (s->sense & irq_mask) {
+/* level-triggered */
+if (s->event & irq_mask) {
+/* high-sensitive */
+raise = level;
+} else {
+/* low-sensitive */
+raise = !level;
+}
+s->raw = deposit64(s->raw, irq, 1, raise);
+} else {
+uint64_t old_level = s->level & irq_mask;
+
+/* edge-triggered */
+if (s->dual_edge & irq_mask) {
+raise = (!!old_level) != (!!level);
+} else {
+if (s->event & irq_mask) {
+/* rising-sensitive */
+raise = !old_level && level;
+} else {
+/* falling-sensitive */
+raise = old_lev

Re: [Qemu-devel] [PATCH v4 0/4] Add ASPEED AST2400 SoC and OpenPower BMC machine

2016-03-15 Thread Andrew Jeffery
On Tue, 2016-03-15 at 11:25 +0100, Cédric Le Goater wrote:
> On 03/15/2016 06:01 AM, Andrew Jeffery wrote:
> > On Tue, 2016-03-15 at 12:34 +0800, Jeremy Kerr wrote:
> > > Hi Andrew,
> > > 
> > > > This patch series models enough of the ASPEED AST2400 ARM9 SoC[0] to
> > > > boot an aspeed_defconfig Linux kernel[1][2]. Specifically, the series
> > > > implements the ASPEED timer and VIC devices, integrates them into an
> > > > AST2400 SoC and exposes it all through a new opbmc2400 machine. The
> > > > device model patches only partially implement the hardware features of
> > > > the timer and VIC, again mostly just enough to boot Linux.
> > > 
> > > Awesome! Nice to have these patches escaping the lab :)
> > > 
> > > In terms of naming suggestions: I think this depends on what we're
> > > looking to emulate here. I see two options:
> > > 
> > > The qemu platform becomes a "reference" for OpenPOWER bmc hardware, but
> > > doesn't necessarily align with an actual machine. In that case,
> > > something generic like opbmc- would make sense.
> > > 
> > > On the other hand, if we'd like to create qemu platforms that represent
> > > actual machines (eg, the OpenPOWER "palmetto" machine), then
> > > -bmc would seem more appropriate. In this case, the machine
> > > name would be palmetto-bmc. No need to include the SoC name in that, as
> > > it's defined by the hardware implementation.
> > > 
> > > I think the latter option may be more generally useful.
> > 
> > Okay, agreed, I'll rework the change to use palmetto-bmc for the
> > machine name. Thanks for the feedback.
> 
> Yes. palmetto-bmc is good choice. Palmetto is a reference machine
> for OpenPOWER. 
> 
> May be change also :
> 
> +mc->desc = "OpenPOWER AST2400 BMC (ARM926EJ-S)";
> 
> to reflect that choice.

Will do!

Thanks,

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v4 1/4] hw/timer: Add ASPEED timer device model

2016-03-15 Thread Andrew Jeffery
On Tue, 2016-03-15 at 14:14 +0100, Cédric Le Goater wrote:
> On 03/14/2016 05:13 AM, Andrew Jeffery wrote:
> > Implement basic ASPEED timer functionality for the AST2400 SoC[1]: Up to
> > 8 timers can independently be configured, enabled, reset and disabled.
> > Some hardware features are not implemented, namely clock value matching
> > and pulse generation, but the implementation is enough to boot the Linux
> > kernel configured with aspeed_defconfig.
> > 
> > [1] http://www.aspeedtech.com/products.php?fPath=20=376
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> 
> Looks good. One stylistic comment and a possible compile break in 
> timer_to_ctrl(). 
> 
> > 
> > ---
> > Since v3:
> >   * Drop unnecessary mention of VMStateDescription in timer_to_ctrl 
> > description
> >   * Mention hw/timer/a9gtimer.c with respect to clock value matching
> >   * Add missing VMSTATE_END_OF_LIST() to vmstate_aspeed_timer_state
> > 
> > Since v2:
> >   * Improve handling of timer configuration with respect to enabled state
> >   * Remove redundant enabled member from AspeedTimer
> >   * Implement VMStateDescriptions
> >   * Fix interrupt behaviour (edge triggered, both edges)
> >   * Fix various issues with trace-event declarations
> >   * Include qemu/osdep.h
> > 
> > Since v1:
> >   * Refactor initialisation of and respect requested clock rates 
> > (APB/External)
> >   * Simplify some index calculations
> >   * Use tracing infrastructure instead of internal DPRINTF
> >   * Enforce access size constraints and alignment in MemoryRegionOps
> > 
> >  default-configs/arm-softmmu.mak |   1 +
> >  hw/timer/Makefile.objs  |   1 +
> >  hw/timer/aspeed_timer.c | 451 
> > 
> >  include/hw/timer/aspeed_timer.h |  59 ++
> >  trace-events|   9 +
> >  5 files changed, 521 insertions(+)
> >  create mode 100644 hw/timer/aspeed_timer.c
> >  create mode 100644 include/hw/timer/aspeed_timer.h
> > 
> > diff --git a/default-configs/arm-softmmu.mak 
> > b/default-configs/arm-softmmu.mak
> > index a9f82a1..2bcd236 100644
> > --- a/default-configs/arm-softmmu.mak
> > +++ b/default-configs/arm-softmmu.mak
> > @@ -110,3 +110,4 @@ CONFIG_IOH3420=y
> >  CONFIG_I82801B11=y
> >  CONFIG_ACPI=y
> >  CONFIG_SMBIOS=y
> > +CONFIG_ASPEED_SOC=y
> > diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
> > index 5cfea6e..003c14f 100644
> > --- a/hw/timer/Makefile.objs
> > +++ b/hw/timer/Makefile.objs
> > @@ -32,3 +32,4 @@ obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
> >  obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
> >  
> >  common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
> > +common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
> > diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
> > new file mode 100644
> > index 000..0e82178
> > --- /dev/null
> > +++ b/hw/timer/aspeed_timer.c
> > @@ -0,0 +1,452 @@
> > +/*
> > + * ASPEED AST2400 Timer
> > + *
> > + * Andrew Jeffery <and...@aj.id.au>
> > + *
> > + * Copyright (C) 2016 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 "hw/ptimer.h"
> > +#include "hw/sysbus.h"
> > +#include "hw/timer/aspeed_timer.h"
> > +#include "qemu-common.h"
> > +#include "qemu/bitops.h"
> > +#include "qemu/main-loop.h"
> > +#include "qemu/timer.h"
> > +#include "trace.h"
> > +
> > +#define TIMER_NR_REGS 4
> > +
> > +#define TIMER_CTRL_BITS 4
> > +#define TIMER_CTRL_MASK ((1 << TIMER_CTRL_BITS) - 1)
> > +
> > +#define TIMER_CLOCK_USE_EXT true
> > +#define TIMER_CLOCK_EXT_HZ 100
> > +#define TIMER_CLOCK_USE_APB false
> > +#define TIMER_CLOCK_APB_HZ 2400
> > +
> > +#define TIMER_REG_STATUS 0
> > +#define TIMER_REG_RELOAD 1
> > +#define TIMER_REG_MATCH_FIRST 2
> > +#define TIMER_REG_MATCH_SECOND 3
> > +
> > +#define TIMER_FIRST_CAP_PULSE 4
> > +
> > +enum timer_ctrl_op {
> > +op_enable = 0,
> > +op_external_clock,
> > +op_overflow_interrupt,
> > +op_pulse_enable
> > +};
> > +
> > +/**
> > + * Avoid mutual references between AspeedTimerCtrlState and As

Re: [Qemu-devel] [PATCH v4 1/4] hw/timer: Add ASPEED timer device model

2016-03-15 Thread Andrew Jeffery
Hi Dmitry,

On Tue, 2016-03-15 at 21:14 +0300, Dmitry Osipenko wrote:
> Hello Andrew,
> 
> 14.03.2016 07:13, Andrew Jeffery пишет:
> > Implement basic ASPEED timer functionality for the AST2400 SoC[1]: Up to
> > 8 timers can independently be configured, enabled, reset and disabled.
> > Some hardware features are not implemented, namely clock value matching
> > and pulse generation, but the implementation is enough to boot the Linux
> > kernel configured with aspeed_defconfig.
> > 
> 
> [snip]
> 
> > +static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int 
> > reg,
> > +   uint32_t value)
> > +{
> > +AspeedTimer *t;
> > +
> > +g_assert(timer >= 0 && timer < ASPEED_TIMER_NR_TIMERS);
> 
> This would never fail, wouldn't it?

You're right, it shouldn't: I put it in as a sanity check and some
"active" documentation. I'm happy to remove it if you think just adds
noise.

> 
> [snip]
> 
> > +static void aspeed_timer_write(void *opaque, hwaddr offset, uint64_t value,
> > +   unsigned size)
> > +{
> > +const uint32_t tv = (uint32_t)(value & 0x);
> > +const int reg = (offset & 0xf) / 4;
> > +AspeedTimerCtrlState *s = opaque;
> > +
> > +switch (offset) {
> > +/* Control Registers */
> > +case 0x30:
> > +aspeed_timer_set_ctrl(s, tv);
> > +break;
> > +case 0x34:
> > +aspeed_timer_set_ctrl2(s, tv);
> > +break;
> > +/* Timer Registers */
> > +case 0x00 ... 0x2c:
> > +aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS), reg, tv);
> > +break;
> > +case 0x40 ... 0x8c:
> > +aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS) - 1, reg, tv);
> > +break;
> 
> 
> [snip]
> 
> > +static void aspeed_init_one_timer(AspeedTimerCtrlState *s, uint8_t id)
> > +{
> > +QEMUBH *bh;
> > +AspeedTimer *t = >timers[id];
> > +
> > +t->id = id;
> > +bh = qemu_bh_new(aspeed_timer_expire, t);
> > +assert(bh);
> > +t->timer = ptimer_init(bh);
> > +assert(t->timer);
> > +}
> 
> I'm wondering why do you need those asserts, it's very unlikely that this 
> code 
> would fail. Have you had any weird issues with it?

No, no weird issues - thanks for pointing them out as I'll remove them:
I put them in when I started developing the series, before
understanding that either call should already have aborted if the
allocations failed.

Thanks for taking a look at the patch!

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v4 0/4] Add ASPEED AST2400 SoC and OpenPower BMC machine

2016-03-14 Thread Andrew Jeffery
On Tue, 2016-03-15 at 12:34 +0800, Jeremy Kerr wrote:
> Hi Andrew,
> 
> > This patch series models enough of the ASPEED AST2400 ARM9 SoC[0] to
> > boot an aspeed_defconfig Linux kernel[1][2]. Specifically, the series
> > implements the ASPEED timer and VIC devices, integrates them into an
> > AST2400 SoC and exposes it all through a new opbmc2400 machine. The
> > device model patches only partially implement the hardware features of
> > the timer and VIC, again mostly just enough to boot Linux.
> 
> Awesome! Nice to have these patches escaping the lab :)
> 
> In terms of naming suggestions: I think this depends on what we're
> looking to emulate here. I see two options:
> 
> The qemu platform becomes a "reference" for OpenPOWER bmc hardware, but
> doesn't necessarily align with an actual machine. In that case,
> something generic like opbmc- would make sense.
> 
> On the other hand, if we'd like to create qemu platforms that represent
> actual machines (eg, the OpenPOWER "palmetto" machine), then
> -bmc would seem more appropriate. In this case, the machine
> name would be palmetto-bmc. No need to include the SoC name in that, as
> it's defined by the hardware implementation.
> 
> I think the latter option may be more generally useful.

Okay, agreed, I'll rework the change to use palmetto-bmc for the
machine name. Thanks for the feedback.

Andrew

signature.asc
Description: This is a digitally signed message part


[Qemu-devel] [PATCH v4 1/4] hw/timer: Add ASPEED timer device model

2016-03-13 Thread Andrew Jeffery
Implement basic ASPEED timer functionality for the AST2400 SoC[1]: Up to
8 timers can independently be configured, enabled, reset and disabled.
Some hardware features are not implemented, namely clock value matching
and pulse generation, but the implementation is enough to boot the Linux
kernel configured with aspeed_defconfig.

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v3:
  * Drop unnecessary mention of VMStateDescription in timer_to_ctrl description
  * Mention hw/timer/a9gtimer.c with respect to clock value matching
  * Add missing VMSTATE_END_OF_LIST() to vmstate_aspeed_timer_state

Since v2:
  * Improve handling of timer configuration with respect to enabled state
  * Remove redundant enabled member from AspeedTimer
  * Implement VMStateDescriptions
  * Fix interrupt behaviour (edge triggered, both edges)
  * Fix various issues with trace-event declarations
  * Include qemu/osdep.h

Since v1:
  * Refactor initialisation of and respect requested clock rates (APB/External)
  * Simplify some index calculations
  * Use tracing infrastructure instead of internal DPRINTF
  * Enforce access size constraints and alignment in MemoryRegionOps

 default-configs/arm-softmmu.mak |   1 +
 hw/timer/Makefile.objs  |   1 +
 hw/timer/aspeed_timer.c | 451 
 include/hw/timer/aspeed_timer.h |  59 ++
 trace-events|   9 +
 5 files changed, 521 insertions(+)
 create mode 100644 hw/timer/aspeed_timer.c
 create mode 100644 include/hw/timer/aspeed_timer.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a9f82a1..2bcd236 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -110,3 +110,4 @@ CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_ACPI=y
 CONFIG_SMBIOS=y
+CONFIG_ASPEED_SOC=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 5cfea6e..003c14f 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -32,3 +32,4 @@ obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
 
 common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
+common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
new file mode 100644
index 000..0e82178
--- /dev/null
+++ b/hw/timer/aspeed_timer.c
@@ -0,0 +1,452 @@
+/*
+ * ASPEED AST2400 Timer
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright (C) 2016 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 "hw/ptimer.h"
+#include "hw/sysbus.h"
+#include "hw/timer/aspeed_timer.h"
+#include "qemu-common.h"
+#include "qemu/bitops.h"
+#include "qemu/main-loop.h"
+#include "qemu/timer.h"
+#include "trace.h"
+
+#define TIMER_NR_REGS 4
+
+#define TIMER_CTRL_BITS 4
+#define TIMER_CTRL_MASK ((1 << TIMER_CTRL_BITS) - 1)
+
+#define TIMER_CLOCK_USE_EXT true
+#define TIMER_CLOCK_EXT_HZ 100
+#define TIMER_CLOCK_USE_APB false
+#define TIMER_CLOCK_APB_HZ 2400
+
+#define TIMER_REG_STATUS 0
+#define TIMER_REG_RELOAD 1
+#define TIMER_REG_MATCH_FIRST 2
+#define TIMER_REG_MATCH_SECOND 3
+
+#define TIMER_FIRST_CAP_PULSE 4
+
+enum timer_ctrl_op {
+op_enable = 0,
+op_external_clock,
+op_overflow_interrupt,
+op_pulse_enable
+};
+
+/**
+ * Avoid mutual references between AspeedTimerCtrlState and AspeedTimer
+ * structs, as it's a waste of memory. The ptimer BH callback needs to know
+ * whether a specific AspeedTimer is enabled, but this information is held in
+ * AspeedTimerCtrlState. So, provide a helper to hoist ourselves from an
+ * arbitrary AspeedTimer to AspeedTimerCtrlState.
+ */
+static inline struct AspeedTimerCtrlState *timer_to_ctrl(AspeedTimer *t)
+{
+AspeedTimer (*timers)[] = (void *)t - (t->id * sizeof(*t));
+return container_of(timers, AspeedTimerCtrlState, timers);
+}
+
+static inline bool timer_ctrl_status(AspeedTimer *t, enum timer_ctrl_op op)
+{
+return !!(timer_to_ctrl(t)->ctrl & BIT(t->id * TIMER_CTRL_BITS + op));
+}
+
+static inline bool timer_enabled(AspeedTimer *t)
+{
+return timer_ctrl_status(t, op_enable);
+}
+
+static inline bool timer_overflow_interrupt(AspeedTimer *t)
+{
+return timer_ctrl_status(t, op_overflow_interrupt);
+}
+
+static inline bool timer_can_pulse(AspeedTimer *t)
+{
+return t->id >= TIMER_FIRST_CAP_PULSE;
+}
+
+static void aspeed_timer_expire(void *opaque)
+{
+AspeedTimer *t = opaque;
+
+/* Only support interrupts on match values of zero for the moment - this is
+ * sufficient to boot an aspeed_defconfig Linux kernel.
+ *
+ * TODO: matching on arbitrary values (see e.g. hw/timer/a9gtimer.c)
+ */
+bool match = !(

[Qemu-devel] [PATCH v4 4/4] hw/arm: Add opbmc2400, an AST2400 OpenPOWER BMC machine

2016-03-13 Thread Andrew Jeffery
The new machine, opbmc2400, is a thin layer over the AST2400
ARM926-based SoC[1]. Between the minimal machine and the current SoC
implementation there is enough functionality to boot an aspeed_defconfig
Linux kernel to userspace.

The machine name is a pragmatic choice, as there doesn't appear to be a
common, formal name for the hardware configuration that isn't generic
(e.g. 'BMC' or 'AST2400').

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v3:

  * Split the machine from the SoC implementation

I've gone the route of inventing a machine name as it seemed there are very few
cases of appending _soc to the chip name or beginning a machine name with mach_
as an outlet for a lack of creativity. It seems only fair to leave the 'ast2400'
namespace to the SoC itself, as it's unlikely that the OpenPOWER BMC is the
SoC's only consumer. I feel that 'opbmc2400' is a reasonable choice; it's not
overly long, and appending the SoC's marketing number leaves the door open to
future OpenPOWER BMC machines with e.g. the AST2500 series SoC.

Since v2:
  * Implement a SOC model to move code out from the machine definition
  * Rework the machine to better use QOM
  * Include qemu/osdep.h
  * Revert back to qemu_log_mask(LOG_UNIMP, ...) in IO handlers

 hw/arm/Makefile.objs |  2 +-
 hw/arm/opbmc2400.c   | 66 
 2 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/opbmc2400.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index f333b7f..7b80460 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -16,4 +16,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
-obj-$(CONFIG_ASPEED_SOC) += ast2400.o
+obj-$(CONFIG_ASPEED_SOC) += ast2400.o opbmc2400.o
diff --git a/hw/arm/opbmc2400.c b/hw/arm/opbmc2400.c
new file mode 100644
index 000..a428364
--- /dev/null
+++ b/hw/arm/opbmc2400.c
@@ -0,0 +1,66 @@
+/*
+ * OpenPOWER BMC with AST2400 SoC
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2016 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 "exec/address-spaces.h"
+#include "hw/arm/arm.h"
+#include "hw/arm/ast2400.h"
+#include "hw/boards.h"
+
+static struct arm_boot_info opbmc2400_binfo = {
+.loader_start = AST2400_SDRAM_BASE,
+.board_id = 0,
+.nb_cpus = 1,
+};
+
+typedef struct OPBMC2400State {
+AST2400State soc;
+MemoryRegion ram;
+} OPBMC2400State;
+
+static void opbmc2400_init(MachineState *machine)
+{
+OPBMC2400State *opbmc2400;
+
+opbmc2400 = g_new0(OPBMC2400State, 1);
+object_initialize(>soc, (sizeof(opbmc2400->soc)), TYPE_AST2400);
+object_property_add_child(OBJECT(machine), "soc", OBJECT(>soc),
+  _abort);
+
+memory_region_allocate_system_memory(>ram, NULL, "ram",
+ ram_size);
+memory_region_add_subregion(get_system_memory(), AST2400_SDRAM_BASE,
+>ram);
+object_property_add_const_link(OBJECT(>soc), "ram",
+   OBJECT(>ram), _abort);
+object_property_set_bool(OBJECT(>soc), true, "realized",
+ _abort);
+
+opbmc2400_binfo.kernel_filename = machine->kernel_filename;
+opbmc2400_binfo.initrd_filename = machine->initrd_filename;
+opbmc2400_binfo.kernel_cmdline = machine->kernel_cmdline;
+opbmc2400_binfo.ram_size = ram_size;
+arm_load_kernel(ARM_CPU(first_cpu), _binfo);
+}
+
+static void opbmc2400_machine_init(MachineClass *mc)
+{
+mc->desc = "OpenPOWER AST2400 BMC (ARM926EJ-S)";
+mc->init = opbmc2400_init;
+mc->max_cpus = 1;
+mc->no_sdcard = 1;
+mc->no_floppy = 1;
+mc->no_cdrom = 1;
+mc->no_sdcard = 1;
+mc->no_parallel = 1;
+}
+
+DEFINE_MACHINE("opbmc2400", opbmc2400_machine_init);
-- 
2.5.0




[Qemu-devel] [PATCH v4 2/4] hw/intc: Add (new) ASPEED VIC device model

2016-03-13 Thread Andrew Jeffery
Implement a basic ASPEED VIC device model for the AST2400 SoC[1], with
enough functionality to boot an aspeed_defconfig Linux kernel. The model
implements the 'new' (revised) register set: While the hardware exposes
both the new and legacy register sets, accesses to the model's legacy
register set will not be serviced (however the access will be logged).

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v3:
  * Switch from g_assert() to qemu_log_mask(LOG_GUEST_ERROR, ...) in guest path

Since v2:
  * Implement all supported interrupt types and configurations
  * Implement a VMStateDescription
  * Log accesses to legacy IO space
  * Add documentation on some implementation and hardware details
  * Switch to extract64/deposit64 where possible
  * Drop int_ prefix from some struct member names
  * Fix various issues with trace-event declarations
  * Include qemu/osdep.h

 hw/intc/Makefile.objs|   1 +
 hw/intc/aspeed_vic.c | 339 +++
 include/hw/intc/aspeed_vic.h |  48 ++
 trace-events |   7 +
 4 files changed, 395 insertions(+)
 create mode 100644 hw/intc/aspeed_vic.c
 create mode 100644 include/hw/intc/aspeed_vic.h

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 6a13a39..0e47f0f 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -31,3 +31,4 @@ obj-$(CONFIG_XICS_KVM) += xics_kvm.o
 obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
 obj-$(CONFIG_S390_FLIC) += s390_flic.o
 obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c
new file mode 100644
index 000..b025de9
--- /dev/null
+++ b/hw/intc/aspeed_vic.c
@@ -0,0 +1,339 @@
+/*
+ * ASPEED Interrupt Controller (New)
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2015, 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+/* The hardware exposes two register sets, a legacy set and a 'new' set. The
+ * model implements the 'new' register set, and logs warnings on accesses to
+ * the legacy IO space.
+ *
+ * The hardware uses 32bit registers to manage 51 IRQs, with low and high
+ * registers for each conceptual register. The device model's implementation
+ * uses 64bit data types to store both low and high register values (in the one
+ * member), but must cope with access offset values in multiples of 4 passed to
+ * the callbacks. As such the read() and write() implementations process the
+ * provided offset to understand whether the access is requesting the lower or
+ * upper 32 bits of the 64bit member.
+ *
+ * Additionally, the "Interrupt Enable", "Edge Status" and "Software Interrupt"
+ * fields have separate "enable"/"status" and "clear" registers, where set bits
+ * are written to one or the other to change state (avoiding a
+ * read-modify-write sequence).
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "hw/intc/aspeed_vic.h"
+#include "qemu/bitops.h"
+#include "trace.h"
+
+#define AVIC_NEW_BASE_OFFSET 0x80
+
+#define AVIC_L_MASK 0xU
+#define AVIC_H_MASK 0x0007U
+#define AVIC_EVENT_W_MASK (0x78000ULL << 32)
+
+static void aspeed_vic_update(AspeedVICState *s)
+{
+uint64_t new = (s->raw & s->enable);
+uint64_t flags;
+
+flags = new & s->select;
+trace_aspeed_vic_update_fiq(!!flags);
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->select;
+trace_aspeed_vic_update_irq(!!flags);
+qemu_set_irq(s->irq, !!flags);
+}
+
+static void aspeed_vic_set_irq(void *opaque, int irq, int level)
+{
+uint64_t irq_mask;
+bool raise;
+AspeedVICState *s = (AspeedVICState *)opaque;
+
+if (irq > ASPEED_VIC_NR_IRQS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+  __func__, irq);
+return;
+}
+
+trace_aspeed_vic_set_irq(irq, level);
+
+irq_mask = BIT(irq);
+if (s->sense & irq_mask) {
+/* level-triggered */
+if (s->event & irq_mask) {
+/* high-sensitive */
+raise = level;
+} else {
+/* low-sensitive */
+raise = !level;
+}
+s->raw = deposit64(s->raw, irq, 1, raise);
+} else {
+uint64_t old_level = s->level & irq_mask;
+
+/* edge-triggered */
+if (s->dual_edge & irq_mask) {
+raise = (!!old_level) != (!!level);
+} else {
+if (s->event & irq_mask) {
+/* rising-sensitive */
+raise = !old_level && level;
+} else {
+/* falling-sensitive */
+raise = old_lev

[Qemu-devel] [PATCH v4 3/4] hw/arm: Add ASPEED AST2400 SoC model

2016-03-13 Thread Andrew Jeffery
While the ASPEED AST2400 SoC[1] has a broad range of capabilities this
implementation is minimal, comprising an ARM926 processor, ASPEED VIC
and timer devices, and a 8250 UART.

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v3:

  * Split the SoC from the machine implementation

Since v2:
  * Implement a SOC model to move code out from the machine definition
  * Rework the machine to better use QOM
  * Include qemu/osdep.h
  * Revert back to qemu_log_mask(LOG_UNIMP, ...) in IO handlers

 hw/arm/Makefile.objs |   1 +
 hw/arm/ast2400.c | 137 +++
 include/hw/arm/ast2400.h |  35 
 3 files changed, 173 insertions(+)
 create mode 100644 hw/arm/ast2400.c
 create mode 100644 include/hw/arm/ast2400.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index a711e4d..f333b7f 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -16,3 +16,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
+obj-$(CONFIG_ASPEED_SOC) += ast2400.o
diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
new file mode 100644
index 000..ecd9e1e
--- /dev/null
+++ b/hw/arm/ast2400.c
@@ -0,0 +1,137 @@
+/*
+ * AST2400 SoC
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ * Jeremy Kerr <j...@ozlabs.org>
+ *
+ * Copyright 2016 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 "exec/address-spaces.h"
+#include "hw/arm/ast2400.h"
+#include "hw/char/serial.h"
+
+#define AST2400_UART_5_BASE  0x00184000
+#define AST2400_IOMEM_SIZE   0x0020
+#define AST2400_IOMEM_BASE   0x1E60
+#define AST2400_VIC_BASE 0x1E6C
+#define AST2400_TIMER_BASE   0x1E782000
+
+static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
+static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
+
+/*
+ * IO handlers: simply catch any reads/writes to IO addresses that aren't
+ * handled by a device mapping.
+ */
+
+static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
+  __func__, offset, size);
+return 0;
+}
+
+static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t value,
+unsigned size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
+  __func__, offset, value, size);
+}
+
+static const MemoryRegionOps ast2400_io_ops = {
+.read = ast2400_io_read,
+.write = ast2400_io_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void ast2400_init(Object *obj)
+{
+AST2400State *s = AST2400(obj);
+
+s->cpu = cpu_arm_init("arm926");
+
+object_initialize(>vic, sizeof(s->vic), TYPE_ASPEED_VIC);
+object_property_add_child(obj, "vic", OBJECT(>vic), NULL);
+qdev_set_parent_bus(DEVICE(>vic), sysbus_get_default());
+
+object_initialize(>timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
+object_property_add_child(obj, "timerctrl", OBJECT(>timerctrl), NULL);
+qdev_set_parent_bus(DEVICE(>timerctrl), sysbus_get_default());
+}
+
+static void ast2400_realize(DeviceState *dev, Error **errp)
+{
+int i;
+AST2400State *s = AST2400(dev);
+Error *err = NULL;
+
+/* IO space */
+memory_region_init_io(>iomem, NULL, _io_ops, NULL,
+"ast2400.io", AST2400_IOMEM_SIZE);
+memory_region_add_subregion_overlap(get_system_memory(), 
AST2400_IOMEM_BASE,
+>iomem, -1);
+
+/* VIC */
+object_property_set_bool(OBJECT(>vic), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>vic), 0, AST2400_VIC_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(>vic), 0,
+   qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
+sysbus_connect_irq(SYS_BUS_DEVICE(>vic), 1,
+   qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
+
+/* Timer */
+object_property_set_bool(OBJECT(>timerctrl), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>timerctrl), 0, AST2400_TIMER_BASE);
+for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
+qemu_irq irq = qdev_get_gpio_in(DEVICE(>vic), timer_irqs[i]);
+sysbus_connect_irq(SYS_BUS_DEVICE(>timerctrl), i, irq);
+}
+
+/* UART - attach an 8250 to the IO space as our UART5 */
+if (serial_hds[0]) {
+qemu_irq uart

[Qemu-devel] [PATCH v4 0/4] Add ASPEED AST2400 SoC and OpenPower BMC machine

2016-03-13 Thread Andrew Jeffery
This patch series models enough of the ASPEED AST2400 ARM9 SoC[0] to boot an
aspeed_defconfig Linux kernel[1][2]. Specifically, the series implements the
ASPEED timer and VIC devices, integrates them into an AST2400 SoC and exposes
it all through a new opbmc2400 machine. The device model patches only partially
implement the hardware features of the timer and VIC, again mostly just enough
to boot Linux.

Unfortunately the datasheet describing the devices is not generally available,
but I'll try to add comments to any unclear areas.

The addition of the AST2400 to QEMU is motivated by use of the SoC as a BMC in
OpenPOWER[2][3] machines and the ongoing development of OpenBMC[4]. The
presence of a machine model utilising the AST2400 will help with development
and testing of the OpenBMC stack.

Cheers,

Andrew

[0] http://www.aspeedtech.com/products.php?fPath=20=376
[1] https://github.com/openbmc/linux/tree/dev-4.3
[2] git fetch g...@github.com:openbmc/linux.git dev-4.3
[3] http://openpowerfoundation.org/
[4] https://github.com/open-power/
[5] https://github.com/openbmc/openbmc

Changes since v3:

  Address comments from Peter Maydell, splitting the machine model from
  hw/arm/ast2400.c into hw/arm/opbmc2400.c amongst other minor cleanups to the
  timer and VIC.

Changes since v2:

  This re-roll is a reasonable rework of the patches in the series, which may
  make it difficult to compare v1 to v2.

  Addressed reviews/comments from:
  * Peter Maydell
  * Alexey Kardashevskiy
  * Joel Stanley

Changes since v1:

  Addressed reviews/comments from:
  * Cédric Le Goater

Andrew Jeffery (4):
  hw/timer: Add ASPEED timer device model
  hw/intc: Add (new) ASPEED VIC device model
  hw/arm: Add an ASPEED AST2400 SoC
  hw/arm: Add opbmc2400, an AST2400-based OpenPOWER BMC machine

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/ast2400.c| 137 
 hw/arm/opbmc2400.c  |  66 ++
 hw/intc/Makefile.objs   |   1 +
 hw/intc/aspeed_vic.c| 339 ++
 hw/timer/Makefile.objs  |   1 +
 hw/timer/aspeed_timer.c | 451 
 include/hw/arm/ast2400.h|  35 
 include/hw/intc/aspeed_vic.h|  48 +
 include/hw/timer/aspeed_timer.h |  59 ++
 trace-events|  16 ++
 12 files changed, 1155 insertions(+)
 create mode 100644 hw/arm/ast2400.c
 create mode 100644 hw/arm/opbmc2400.c
 create mode 100644 hw/intc/aspeed_vic.c
 create mode 100644 hw/timer/aspeed_timer.c
 create mode 100644 include/hw/arm/ast2400.h
 create mode 100644 include/hw/intc/aspeed_vic.h
 create mode 100644 include/hw/timer/aspeed_timer.h

-- 
2.5.0




Re: [Qemu-devel] [PATCH v3 2/3] hw/intc: Add (new) ASPEED VIC device model

2016-03-11 Thread Andrew Jeffery
On Fri, 2016-03-11 at 16:03 +0700, Peter Maydell wrote:
> On 5 March 2016 at 11:29, Andrew Jeffery <and...@aj.id.au> wrote:
> > Implement a basic ASPEED VIC device model, enough to boot a Linux kernel
> > configured with aspeed_defconfig. The model implements the 'new'
> > (revised) register set and while the hardware exposes both the new and
> > legacy register sets, accesses to the legacy register set will not
> > be serviced (though the access will be logged).
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> 
> > +static void aspeed_vic_write(void *opaque, hwaddr offset, uint64_t data,
> > + unsigned size)
> > +{
> > +const bool high = !!(offset & 0x4);
> > +hwaddr n_offset = (offset & ~0x4);
> > +AspeedVICState *s = (AspeedVICState *)opaque;
> > +
> > +if (offset < AVIC_NEW_BASE_OFFSET) {
> > +qemu_log_mask(LOG_UNIMP,
> > +  "%s: Ignoring write to legacy registers at 0x%"
> > +  HWADDR_PRIx "[%u] <- 0x%" PRIx64 "\n", __func__, 
> > offset,
> > +  size, data);
> > +return;
> > +}
> > +
> > +n_offset -= AVIC_NEW_BASE_OFFSET;
> > +trace_aspeed_vic_write(offset, size, data);
> > +
> > +/* Given we have members using separate enable/clear registers, 
> > deposit64()
> > + * isn't quite the tool for the job. Instead, relocate the incoming 
> > bits to
> > + * the required bit offset based on the provided access address
> > + */
> > +if (high) {
> > +data &= AVIC_H_MASK;
> > +data <<= 32;
> > +} else {
> > +data &= AVIC_L_MASK;
> > +}
> > +
> > +switch (n_offset) {
> > +case 0x18: /* Interrupt Selection */
> > +/* Register has deposit64() semantics - overwrite requested 32 
> > bits */
> > +if (high) {
> > +s->select &= AVIC_L_MASK;
> > +} else {
> > +s->select &= ((uint64_t) AVIC_H_MASK) << 32;
> > +}
> > +s->select |= data;
> > +break;
> > +case 0x20: /* Interrupt Enable */
> > +s->enable |= data;
> > +break;
> > +case 0x28: /* Interrupt Enable Clear */
> > +s->enable &= ~data;
> > +break;
> > +case 0x30: /* Software Interrupt */
> > +qemu_log_mask(LOG_UNIMP, "%s: Software interrupts unavailable. "
> > +"IRQs requested: 0x%016" PRIx64 "\n", __func__, data);
> > +break;
> > +case 0x38: /* Software Interrupt Clear */
> > +qemu_log_mask(LOG_UNIMP, "%s: Software interrupts unavailable. "
> > +"IRQs to be cleared: 0x%016" PRIx64 "\n", __func__, data);
> > +break;
> > +case 0x50: /* Interrupt Event */
> > +/* Register has deposit64() semantics - overwrite the top four 
> > valid
> > + * IRQ bits, as only the top four IRQs (GPIOs) can change their 
> > event
> > + * type */
> > +g_assert(high);
> 
> Don't assert on conditions that can be triggered by a guest.

Good point, I'll change it to qemu_log_mask(LOG_GUEST_ERROR, ...)

> 
> > +s->event &= ~AVIC_EVENT_W_MASK;
> > +s->event |= (data & AVIC_EVENT_W_MASK);
> > +break;
> > +case 0x58: /* Edge Triggered Interrupt Clear */
> > +s->raw &= ~(data & ~s->sense);
> > +break;
> > +case 0x00: /* IRQ Status */
> > +case 0x08: /* FIQ Status */
> > +case 0x10: /* Raw Interrupt Status */
> > +case 0x40: /* Interrupt Sensitivity */
> > +case 0x48: /* Interrupt Both Edge Trigger Control */
> > +case 0x60: /* Edge Triggered Interrupt Status */
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "%s: Write of read-only register with offset 0x%"
> > +  HWADDR_PRIx "\n", __func__, offset);
> > +break;
> > +
> > +default:
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "%s: Bad register at offset 0x%" HWADDR_PRIx "\n",
> > +  __func__, offset);
> > +break;
> > +}
> > +aspeed_vic_update(s);
> > +}
> 
> Otherwise
> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>

Thanks,

Andrew
> 
> thanks
> -- PMM

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v3 1/3] hw/timer: Add ASPEED timer device model

2016-03-11 Thread Andrew Jeffery
On Fri, 2016-03-11 at 15:56 +0700, Peter Maydell wrote:
> On 5 March 2016 at 11:29, Andrew Jeffery <and...@aj.id.au> wrote:
> > Implement basic AST2400 timer functionality: Up to 8 timers can
> > independently be configured, enabled, reset and disabled. A couple of
> > hardware features are not implemented, namely clock value matching and
> > pulse generation, but the implementation is enough to boot the Linux
> > kernel configured with aspeed_defconfig.
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > ---
> > +/**
> > + * Avoid mutual references between AspeedTimerCtrlState and AspeedTimer
> > + * structs, as it's a waste of memory and it makes implementing
> > + * VMStateDescription a little clunky.
> 
> Not sure what you have in mind with the reference to VMStateDescription
> here. The vmstate struct only has to list the fields which contain
> actual volatile state -- things like backreference pointers to other
> structs aren't volatile state so don't appear.

Good point, looks like I was over-thinking things. I'll remove the part
referencing VMStateDescription.

> 
> > The ptimer BH callback needs to know
> > + * whether a specific AspeedTimer is enabled, but this information is held 
> > in
> > + * AspeedTimerCtrlState. So, provide a helper to hoist ourselves from an
> > + * arbitrary AspeedTimer to AspeedTimerCtrlState.
> > + */
> > +static inline struct AspeedTimerCtrlState *timer_to_ctrl(AspeedTimer *t)
> > +{
> > +AspeedTimer (*timers)[] = (void *)t - (t->id * sizeof(*t));
> > +return container_of(timers, AspeedTimerCtrlState, timers);
> > +}
> 
> > +static void aspeed_timer_expire(void *opaque)
> > +{
> > +AspeedTimer *t = opaque;
> > +
> > +/* Only support interrupts on match values of zero for the moment - 
> > this is
> > + * sufficient to boot an aspeed_defconfig Linux kernel. Non-zero match
> > + * values need some further consideration given the current ptimer API.
> > + * Maybe run multiple ptimers?
> > + */
> 
> See hw/timer/a9gtimer.c for an example of a timer with a comparator
> that can fire when the timer hits an arbitrary comparator value
> (it doesn't use ptimers but the principle is the same -- you set
> the timer to fire at the next interesting event, and then in the
> timer-fired handler you reset the timer to fire whenever the next
> event after that is, if any.) In any case this is probably ok for now.

Thanks for the pointer. I'll leave that change to a future patch given
it looks like this is converging on being acceptable, though I'll
expand the comment to cover a9gtimer.

> 
> > +bool match = !(t->match[0] && t->match[1]);
> > +bool interrupt = timer_overflow_interrupt(t) || match;
> > +if (timer_enabled(t) && interrupt) {
> > +t->level = !t->level;
> > +qemu_set_irq(t->irq, t->level);
> > +}
> > +}
> > +
> 
> Otherwise
> Reviewed-by: Peter Maydell <peter.mayd...@linaro.org>

Thanks!

Andrew

> 
> thanks
> -- PMM

signature.asc
Description: This is a digitally signed message part


[Qemu-devel] [PATCH v3 1/3] hw/timer: Add ASPEED timer device model

2016-03-04 Thread Andrew Jeffery
Implement basic AST2400 timer functionality: Up to 8 timers can
independently be configured, enabled, reset and disabled. A couple of
hardware features are not implemented, namely clock value matching and
pulse generation, but the implementation is enough to boot the Linux
kernel configured with aspeed_defconfig.

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v2:
  * Improve handling of timer configuration with respect to enabled state
  * Remove redundant enabled member from AspeedTimer
  * Implement VMStateDescriptions
  * Fix interrupt behaviour (edge triggered, both edges)
  * Fix various issues with trace-event declarations
  * Include qemu/osdep.h

Since v1:
  * Refactor initialisation of and respect requested clock rates (APB/External)
  * Simplify some index calculations
  * Use tracing infrastructure instead of internal DPRINTF
  * Enforce access size constraints and alignment in MemoryRegionOps

 default-configs/arm-softmmu.mak |   1 +
 hw/timer/Makefile.objs  |   1 +
 hw/timer/aspeed_timer.c | 452 
 include/hw/timer/aspeed_timer.h |  59 ++
 trace-events|   9 +
 5 files changed, 522 insertions(+)
 create mode 100644 hw/timer/aspeed_timer.c
 create mode 100644 include/hw/timer/aspeed_timer.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a9f82a1..2bcd236 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -110,3 +110,4 @@ CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_ACPI=y
 CONFIG_SMBIOS=y
+CONFIG_ASPEED_SOC=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 5cfea6e..003c14f 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -32,3 +32,4 @@ obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
 
 common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
+common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
new file mode 100644
index 000..f1d232c
--- /dev/null
+++ b/hw/timer/aspeed_timer.c
@@ -0,0 +1,452 @@
+/*
+ * ASPEED AST2400 Timer
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright (C) 2016 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 "hw/ptimer.h"
+#include "hw/sysbus.h"
+#include "hw/timer/aspeed_timer.h"
+#include "qemu-common.h"
+#include "qemu/bitops.h"
+#include "qemu/main-loop.h"
+#include "qemu/timer.h"
+#include "trace.h"
+
+#define TIMER_NR_REGS 4
+
+#define TIMER_CTRL_BITS 4
+#define TIMER_CTRL_MASK ((1 << TIMER_CTRL_BITS) - 1)
+
+#define TIMER_CLOCK_USE_EXT true
+#define TIMER_CLOCK_EXT_HZ 100
+#define TIMER_CLOCK_USE_APB false
+#define TIMER_CLOCK_APB_HZ 2400
+
+#define TIMER_REG_STATUS 0
+#define TIMER_REG_RELOAD 1
+#define TIMER_REG_MATCH_FIRST 2
+#define TIMER_REG_MATCH_SECOND 3
+
+#define TIMER_FIRST_CAP_PULSE 4
+
+enum timer_ctrl_op {
+op_enable = 0,
+op_external_clock,
+op_overflow_interrupt,
+op_pulse_enable
+};
+
+/**
+ * Avoid mutual references between AspeedTimerCtrlState and AspeedTimer
+ * structs, as it's a waste of memory and it makes implementing
+ * VMStateDescription a little clunky. The ptimer BH callback needs to know
+ * whether a specific AspeedTimer is enabled, but this information is held in
+ * AspeedTimerCtrlState. So, provide a helper to hoist ourselves from an
+ * arbitrary AspeedTimer to AspeedTimerCtrlState.
+ */
+static inline struct AspeedTimerCtrlState *timer_to_ctrl(AspeedTimer *t)
+{
+AspeedTimer (*timers)[] = (void *)t - (t->id * sizeof(*t));
+return container_of(timers, AspeedTimerCtrlState, timers);
+}
+
+static inline bool timer_ctrl_status(AspeedTimer *t, enum timer_ctrl_op op)
+{
+return !!(timer_to_ctrl(t)->ctrl & BIT(t->id * TIMER_CTRL_BITS + op));
+}
+
+static inline bool timer_enabled(AspeedTimer *t)
+{
+return timer_ctrl_status(t, op_enable);
+}
+
+static inline bool timer_overflow_interrupt(AspeedTimer *t)
+{
+return timer_ctrl_status(t, op_overflow_interrupt);
+}
+
+static inline bool timer_can_pulse(AspeedTimer *t)
+{
+return t->id >= TIMER_FIRST_CAP_PULSE;
+}
+
+static void aspeed_timer_expire(void *opaque)
+{
+AspeedTimer *t = opaque;
+
+/* Only support interrupts on match values of zero for the moment - this is
+ * sufficient to boot an aspeed_defconfig Linux kernel. Non-zero match
+ * values need some further consideration given the current ptimer API.
+ * Maybe run multiple ptimers?
+ */
+bool match = !(t->match[0] && t->match[1]);
+bool interrupt = timer_overflow_interrupt(t) || match;
+if (timer_enabled(t) && interrupt) {
+t->level = !t->level;
+

[Qemu-devel] [PATCH v3 2/3] hw/intc: Add (new) ASPEED VIC device model

2016-03-04 Thread Andrew Jeffery
Implement a basic ASPEED VIC device model, enough to boot a Linux kernel
configured with aspeed_defconfig. The model implements the 'new'
(revised) register set and while the hardware exposes both the new and
legacy register sets, accesses to the legacy register set will not
be serviced (though the access will be logged).

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v2:
  * Implement all supported interrupt types and configurations
  * Implement a VMStateDescription
  * Log accesses to legacy IO space
  * Add documentation on some implementation and hardware details
  * Switch to extract64/deposit64 where possible
  * Drop int_ prefix from some struct member names
  * Fix various issues with trace-event declarations
  * Include qemu/osdep.h

 hw/intc/Makefile.objs|   1 +
 hw/intc/aspeed_vic.c | 335 +++
 include/hw/intc/aspeed_vic.h |  48 +++
 trace-events |   7 +
 4 files changed, 391 insertions(+)
 create mode 100644 hw/intc/aspeed_vic.c
 create mode 100644 include/hw/intc/aspeed_vic.h

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 6a13a39..0e47f0f 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -31,3 +31,4 @@ obj-$(CONFIG_XICS_KVM) += xics_kvm.o
 obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
 obj-$(CONFIG_S390_FLIC) += s390_flic.o
 obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c
new file mode 100644
index 000..8cfaa02
--- /dev/null
+++ b/hw/intc/aspeed_vic.c
@@ -0,0 +1,335 @@
+/*
+ * ASPEED Interrupt Controller (New)
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ *
+ * Copyright 2015, 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+/* The hardware exposes two register sets, a legacy set and a 'new' set. The
+ * model implements the 'new' register set, and logs warnings on accesses to
+ * the legacy IO space.
+ *
+ * The hardware uses 32bit registers to manage 51 IRQs, with low and high
+ * registers for each conceptual register. The device model's implementation
+ * uses 64bit data types to store both low and high register values (in the one
+ * member), but must cope with access offset values in multiples of 4 passed to
+ * the callbacks. As such the read() and write() implementations process the
+ * provided offset to understand whether the access is requesting the lower or
+ * upper 32 bits of the 64bit member.
+ *
+ * Additionally, the "Interrupt Enable", "Edge Status" and "Software Interrupt"
+ * fields have separate "enable"/"status" and "clear" registers, where set bits
+ * are written to one or the other to change state (avoiding a
+ * read-modify-write sequence).
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "hw/intc/aspeed_vic.h"
+#include "qemu/bitops.h"
+#include "trace.h"
+
+#define AVIC_NEW_BASE_OFFSET 0x80
+
+#define AVIC_L_MASK 0xU
+#define AVIC_H_MASK 0x0007U
+#define AVIC_EVENT_W_MASK (0x78000ULL << 32)
+
+static void aspeed_vic_update(AspeedVICState *s)
+{
+uint64_t new = (s->raw & s->enable);
+uint64_t flags;
+
+flags = new & s->select;
+trace_aspeed_vic_update_fiq(!!flags);
+qemu_set_irq(s->fiq, !!flags);
+
+flags = new & ~s->select;
+trace_aspeed_vic_update_irq(!!flags);
+qemu_set_irq(s->irq, !!flags);
+}
+
+static void aspeed_vic_set_irq(void *opaque, int irq, int level)
+{
+uint64_t irq_mask;
+bool raise;
+AspeedVICState *s = (AspeedVICState *)opaque;
+
+if (irq > ASPEED_VIC_NR_IRQS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Out-of-range interrupt number: 
%d\n",
+  __func__, irq);
+return;
+}
+
+trace_aspeed_vic_set_irq(irq, level);
+
+irq_mask = BIT(irq);
+if (s->sense & irq_mask) {
+/* level-triggered */
+if (s->event & irq_mask) {
+/* high-sensitive */
+raise = level;
+} else {
+/* low-sensitive */
+raise = !level;
+}
+s->raw = deposit64(s->raw, irq, 1, raise);
+} else {
+uint64_t old_level = s->level & irq_mask;
+
+/* edge-triggered */
+if (s->dual_edge & irq_mask) {
+raise = (!!old_level) != (!!level);
+} else {
+if (s->event & irq_mask) {
+/* rising-sensitive */
+raise = !old_level && level;
+} else {
+/* falling-sensitive */
+raise = old_level && !level;
+}
+}
+if (raise) {
+s->raw = deposit64(s->raw, irq, 1, raise);
+}
+}
+s->level = d

[Qemu-devel] [PATCH v3 3/3] hw/arm: Add ASPEED AST2400 machine model

2016-03-04 Thread Andrew Jeffery
Adds an AST2400 ARM machine[1], based around an AST2400 SOC containing an
ARM926 processor, ASPEED VIC and timer devices, and a 8250 UART. The new
machine type is functional enough to boot an aspeed_defconfig Linux
kernel to userspace.

[1] http://www.aspeedtech.com/products.php?fPath=20=376

Signed-off-by: Andrew Jeffery <and...@aj.id.au>
---
Since v2:
  * Implement a SOC model to move code out from the machine definition
  * Rework the machine to better use QOM
  * Include qemu/osdep.h
  * Revert back to qemu_log_mask(LOG_UNIMP, ...) in IO handlers

Since v1:

 hw/arm/Makefile.objs |   1 +
 hw/arm/ast2400.c | 208 +++
 2 files changed, 209 insertions(+)
 create mode 100644 hw/arm/ast2400.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index a711e4d..f333b7f 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -16,3 +16,4 @@ obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
 obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
+obj-$(CONFIG_ASPEED_SOC) += ast2400.o
diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
new file mode 100644
index 000..74aca49
--- /dev/null
+++ b/hw/arm/ast2400.c
@@ -0,0 +1,208 @@
+/*
+ * ASPEED AST2400
+ *
+ * Andrew Jeffery <and...@aj.id.au>
+ * Jeremy Kerr <j...@ozlabs.org>
+ *
+ * Copyright 2016 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 "exec/address-spaces.h"
+#include "hw/arm/arm.h"
+#include "hw/boards.h"
+#include "hw/char/serial.h"
+#include "hw/sysbus.h"
+#include "hw/intc/aspeed_vic.h"
+#include "hw/timer/aspeed_timer.h"
+#include "target-arm/cpu.h"
+#include "trace.h"
+
+#define AST2400_UART_5_BASE  0x00184000
+#define AST2400_IOMEM_SIZE   0x0020
+#define AST2400_IOMEM_BASE   0x1E60
+#define AST2400_VIC_BASE 0x1E6C
+#define AST2400_TIMER_BASE   0x1E782000
+#define AST2400_SDRAM_BASE   0x4000
+
+static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
+static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
+
+static struct arm_boot_info ast2400_binfo = {
+.loader_start = AST2400_SDRAM_BASE,
+.board_id = 0,
+.nb_cpus = 1,
+};
+
+/*
+ * IO handlers: simply catch any reads/writes to IO addresses that aren't
+ * handled by a device mapping.
+ */
+
+static uint64_t ast2400_soc_io_read(void *p, hwaddr offset, unsigned size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
+  __func__, offset, size);
+return 0;
+}
+
+static void ast2400_soc_io_write(void *opaque, hwaddr offset, uint64_t value,
+unsigned size)
+{
+qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
+  __func__, offset, value, size);
+}
+
+static const MemoryRegionOps ast2400_soc_io_ops = {
+.read = ast2400_soc_io_read,
+.write = ast2400_soc_io_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+typedef struct AST2400SOCState {
+/*< private >*/
+DeviceState parent;
+
+/*< public >*/
+ARMCPU *cpu;
+MemoryRegion iomem;
+AspeedVICState vic;
+AspeedTimerCtrlState timerctrl;
+} AST2400SOCState;
+
+#define TYPE_AST2400_SOC "ast2400-soc"
+#define AST2400_SOC(obj) OBJECT_CHECK(AST2400SOCState, (obj), TYPE_AST2400_SOC)
+
+static void ast2400_soc_init(Object *obj)
+{
+AST2400SOCState *s = AST2400_SOC(obj);
+
+s->cpu = cpu_arm_init("arm926");
+
+object_initialize(>vic, sizeof(s->vic), TYPE_ASPEED_VIC);
+object_property_add_child(obj, "vic", OBJECT(>vic), NULL);
+qdev_set_parent_bus(DEVICE(>vic), sysbus_get_default());
+
+object_initialize(>timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
+object_property_add_child(obj, "timerctrl", OBJECT(>timerctrl), NULL);
+qdev_set_parent_bus(DEVICE(>timerctrl), sysbus_get_default());
+}
+
+static void ast2400_soc_realize(DeviceState *dev, Error **errp)
+{
+int i;
+AST2400SOCState *s = AST2400_SOC(dev);
+Error *err = NULL;
+
+/* IO space */
+memory_region_init_io(>iomem, NULL, _soc_io_ops, NULL,
+"ast2400.io", AST2400_IOMEM_SIZE);
+memory_region_add_subregion(get_system_memory(), AST2400_IOMEM_BASE,
+>iomem);
+
+/* VIC */
+object_property_set_bool(OBJECT(>vic), true, "realized", );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(>vic), 0, AST2400_VIC_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(>vic), 0,
+   qdev_get_gpio_in(DEVICE(

[Qemu-devel] [PATCH v3 0/3] Add ASPEED AST2400 machine model

2016-03-04 Thread Andrew Jeffery
This patch series models enough of the ASPEED AST2400 ARM9 SoC[0] to boot an
aspeed_defconfig Linux kernel[1]. Specifically, the series implements the timer
and VIC devices and integrates them into a new ast2400 machine through a
AST2400SOC model. The device model patches only partially implement the
hardware features of the timer and VIC, again mostly just enough to boot Linux.

Unfortunately the datasheet describing the devices is not generally available,
but I'll try to add comments to any unclear areas.

The addition of the AST2400 to QEMU is motivated by use of the SoC as a BMC in
OpenPOWER[2][3] machines and the ongoing development of OpenBMC[4]. The
presence of a machine model for the AST2400 will help with development and
testing of the OpenBMC stack.

Cheers,

Andrew

[0] http://www.aspeedtech.com/products.php?fPath=20=376
[1] git fetch g...@github.com:openbmc/linux.git dev-4.3
[2] http://openpowerfoundation.org/
[3] https://github.com/open-power/
[4] https://github.com/openbmc/openbmc

Changes since v2:

  This re-roll is a reasonable rework of the patches in the series, which may
  make it difficult to compare v1 to v2.

  Addressed reviews/comments from:
  * Peter Maydell
  * Alexey Kardashevskiy
  * Joel Stanley

Changes since v1:

  Addressed reviews/comments from:
  * Cédric Le Goater

Andrew Jeffery (3):
  hw/timer: Add ASPEED timer device model
  hw/intc: Add (new) ASPEED VIC device model
  hw/arm: Add ASPEED AST2400 machine model

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/ast2400.c| 208 ++
 hw/intc/Makefile.objs   |   1 +
 hw/intc/aspeed_vic.c| 335 +
 hw/timer/Makefile.objs  |   1 +
 hw/timer/aspeed_timer.c | 452 
 include/hw/intc/aspeed_vic.h|  48 +
 include/hw/timer/aspeed_timer.h |  59 ++
 trace-events|  16 ++
 10 files changed, 1122 insertions(+)
 create mode 100644 hw/arm/ast2400.c
 create mode 100644 hw/intc/aspeed_vic.c
 create mode 100644 hw/timer/aspeed_timer.c
 create mode 100644 include/hw/intc/aspeed_vic.h
 create mode 100644 include/hw/timer/aspeed_timer.h

-- 
2.5.0




Re: [Qemu-devel] [Qemu-arm] [PATCH v2 2/3] hw/intc: Add (new) ASPEED AST2400 AVIC device model

2016-03-03 Thread Andrew Jeffery
On Thu, 2016-03-03 at 08:39 +, Peter Maydell wrote:
> On 3 March 2016 at 05:14, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > On Thu, 2016-02-25 at 16:29 +, Peter Maydell wrote:
> > > 
> > > > 
> > > > +case 0x20: /* Interrupt Enable */
> > > > +s->int_enable |= data;
> > > Are you sure this only ORs in new 1 bits?
> > As in, am I sure I only want to take the newly set bits? If so, yes, as
> > the the following register serves to clear the field's set bits:
> > 
> > > 
> > > 
> > > > 
> > > > +break;
> > > > +case 0x28: /* Interrupt Enable Clear */
> > > > +s->int_enable &= ~data;
> > > > +break;
> > The 'int_enable', 'int_trigger' and 'edge_status' fields all use the pa
> > ttern of separate set and clear registers (the remaining registers may
> > benefit from the extract64/deposit64 helpers, I'll think about that
> > further). I'll add some comments to help clear this up.
> > 
> > Otherwise, can you rephrase the question? At face value it seems like
> > you're implying that I'm doing more than ORing in the new 1 bits?
> It was just that the register name didn't imply a set-bits-only
> semantic and some of the other registers looked like they were
> also incorrectly not handling updates right.

That's a fair call: The comments I added were the documented register
names, which don't provide huge insight on their own. This is probably
a less-than-ideal approach given the datasheet is largely unavailable.
As mentioned above I'll add some comments on the different access
patterns and where they apply to try clear this up.

Cheers,

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [Qemu-arm] [PATCH v2 2/3] hw/intc: Add (new) ASPEED AST2400 AVIC device model

2016-03-02 Thread Andrew Jeffery
On Thu, 2016-02-25 at 16:29 +, Peter Maydell wrote:
> > +case 0x20: /* Interrupt Enable */
> > +s->int_enable |= data;
> 
> Are you sure this only ORs in new 1 bits?

As in, am I sure I only want to take the newly set bits? If so, yes, as
the the following register serves to clear the field's set bits:

> 
> > +break;
> > +case 0x28: /* Interrupt Enable Clear */
> > +s->int_enable &= ~data;
> > +break;

The 'int_enable', 'int_trigger' and 'edge_status' fields all use the pa
ttern of separate set and clear registers (the remaining registers may
benefit from the extract64/deposit64 helpers, I'll think about that
further). I'll add some comments to help clear this up.

Otherwise, can you rephrase the question? At face value it seems like
you're implying that I'm doing more than ORing in the new 1 bits?

Andrew

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [Qemu-arm] [PATCH v2 2/3] hw/intc: Add (new) ASPEED AST2400 AVIC device model

2016-03-01 Thread Andrew Jeffery
Hi Peter,
  
On Thu, 2016-02-25 at 16:29 +, Peter Maydell wrote:
> On 16 February 2016 at 11:34, Andrew Jeffery <and...@aj.id.au> wrote:
> > Implement a minimal ASPEED AVIC device model, enough to boot a Linux
> > kernel configured with aspeed_defconfig. The VIC implements the 'new'
> > register set and expects this to be reflected in the device tree.
> 
> What do we mean by "new" here? Were there multiple revisions of
> this hardware?

Yes, I'll try rework the commit message to clear this up.

> 
> > The implementation is a little awkward as the hardware uses 32bit
> > registers to manage 51 IRQs, and makes use of low and high registers for
> > each conceptual register. The model's implementation uses 64bit data
> > types to store the register values but must cope with access offset values
> > in multiples of 4 passed to the callbacks. As such the read() and
> > write() implementations process the provided offset to understand
> > whether the access is requesting the lower or upper 32bits of the 64bit
> > quantity.

FWIW I've moved this to a comment in the source as suggested in an off
-list review by Alexey Kardashevskiy.

> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > ---
> >  hw/intc/Makefile.objs|   1 +
> >  hw/intc/aspeed_vic.c | 256 
> > +++
> >  include/hw/intc/aspeed_vic.h |  40 +++
> >  trace-events |   9 ++
> >  4 files changed, 306 insertions(+)
> >  create mode 100644 hw/intc/aspeed_vic.c
> >  create mode 100644 include/hw/intc/aspeed_vic.h
> > 
> > diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
> > index 6a13a39..0e47f0f 100644
> > --- a/hw/intc/Makefile.objs
> > +++ b/hw/intc/Makefile.objs
> > @@ -31,3 +31,4 @@ obj-$(CONFIG_XICS_KVM) += xics_kvm.o
> >  obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
> >  obj-$(CONFIG_S390_FLIC) += s390_flic.o
> >  obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
> > +obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
> > diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c
> > new file mode 100644
> > index 000..c000936
> > --- /dev/null
> > +++ b/hw/intc/aspeed_vic.c
> > @@ -0,0 +1,256 @@
> > +/*
> > + * ASPEED Interrupt Controller (New)
> > + *
> > + * Andrew Jeffery <and...@aj.id.au>
> > + *
> > + * Copyright 2015, 2016 IBM Corp.
> > + *
> > + * This code is licensed under the GPL version 2 or later.  See
> > + * the COPYING file in the top-level directory.
> > + *
> > + * Based off of the i.MX31 Vectored Interrupt Controller
> > + *
> > + * Note that this device model does not implement the legacy register 
> > space.
> > + * The assumption is that the device base address is exposed such that all
> > + * offsets are calculated relative to the address of the first "new" 
> > register.
> 
> Is there real hardware that doesn't implement the legacy register
> space?

I don't immediately know the answer, but both the AST2400 and AST2500
retain the legacy register set (in addition to providing the new set).

>  Should we be at least implementing it enough to do a
> LOG_UNIMP log of the fact we don't implement it?

Yeah that sounds useful, I'll look into it.

> 
> > + */
> > +#include 
> 
> Missing newline before #include. As with the other file, include
> qemu/osdep.h first. (If you rebase on current master you'll find you
> get compile errors otherwise.)
> > +#include "hw/intc/aspeed_vic.h"
> > +#include "trace.h"
> > +
> > +#define AVIC_L_MASK 0x
> 
> This needs a 'U' suffix or at least one of the compilers we build
> with will complain.

Okay. Out of interest, what compiler will complain?

> 
> > +#define AVIC_H_MASK 0x7FFF
> > +#define AVIC_INT_EVENT_W_MASK (UINT64_C(0x78000) << 32)
> 
> We generally use the ULL suffix rather than UINT64_C().

Okay.


> > +
> > +static void aspeed_vic_update(AspeedVICState *s)
> > +{
> > +int i;
> > +uint64_t new = (s->edge_status & s->int_enable);
> > +uint64_t flags;
> > +
> > +flags = new & s->int_select;
> > +qemu_set_irq(s->fiq, !!flags);
> > +trace_aspeed_vic_update_fiq(!!flags);
> > +
> > +flags = new & ~s->int_select;
> > +if (!flags) {
> > +qemu_set_irq(s->irq, !!flags);
> > +trace_aspeed_vic_update_all_fiq();
> > +return;
> > +}
> > +
> > +for (i = 0; i < ASPEED_VIC_NR_IRQS; i++) {
> >

Re: [Qemu-devel] [Qemu-arm] [PATCH v2 1/3] hw/timer: Add ASPEED AST2400 timer device model

2016-02-28 Thread Andrew Jeffery
On Fri, 2016-02-26 at 10:20 +, Peter Maydell wrote:
> On 26 February 2016 at 03:14, Andrew Jeffery <and...@aj.id.au> wrote:
> > 
> > Hi Peter,
> > 
> > On Thu, 2016-02-25 at 16:11 +, Peter Maydell wrote:
> > > 
> > > On 16 February 2016 at 11:34, Andrew Jeffery <and...@aj.id.au> wrote:
> > > > 
> > > > Implement basic AST2400 timer functionality: Timers can be configured,
> > > > enabled, reset and disabled.
> > > > 
> > > > A number of hardware features are not implemented:
> > > > 
> > > > * Timer Overflow interrupts
> > > > * Clock value matching
> > > > * Pulse generation
> > > > 
> > > > The implementation is enough to boot the Linux kernel configured with
> > > > aspeed_defconfig.
> > > Thanks; this mostly looks in reasonable shape; I have some comments below.
> > > 
> > > Do we have a datasheet for this chip ?
> > Unfortunately I don't know of a publicly available datasheet. What's
> > the best way to proceed in this case?
> We have devices in the tree that are either based on non-public datasheets
> or occasionally reverse engineered from Linux kernel drivers. That's OK,
> but it's nice to be clear in a comment at the top what the source is,
> so people maintaining it later know how much to trust the current code
> and (if possible) where to look for clarification.

No worries, I'll add notes in the header comments for each of the new
files.

> 
> > 
> > > 
> > > All source files need to #include "qemu/osdep.h" as their first
> > > include. That then means you don't need to include assert.h or
> > > stdio.h yourself.
> > > 
> > > What do we need from qemu/main-loop.h?
> > I'm using it for qemu_bh_new() which is required by ptimer, who registers
> > the aspeed_timer_tick() callback into the main loop timer handling.
> OK, no problem.
> 
> > 
> > > 
> > > > 
> > > > +static void aspeed_timer_irq_update(AspeedTimer *t)
> > > > +{
> > > > +qemu_set_irq(t->irq, t->enabled);
> > > Surely the timer doesn't assert its IRQ line all
> > > the time it's enabled? This doesn't look like the right condition.
> > So I think this is correct despite how it looks. There's some cruft
> > from modelling the implementation off of another timer that's probably
> > obscuring things, which should be fixed. aspeed_timer_irq_update()
> > is only called from aspeed_timer_tick(), so I'll just merge the two.
> > Then by renaming aspeed_timer_tick() to aspeed_timer_expire() as
> > mentioned above, this won't look so strange? I've read through the
> > timer handling code (the processing loop in timerlist_run_timers())
> > and my understanding is it has the behaviour we want - callback on
> > expiry, not on ticks - which is not how it reads as above.
> Usually functions in QEMU called thingy_irq_update() are the ones
> that do "look at current state of device and assert IRQ as
> necessary"; often this is "mask irq raw state against some
> irq-masking bit". Merging this into the timer expire function will
> probably help. (Is there no register bit that the guest can query
> that indicates "timer expired" or "raw interrupt state" ?)

It doesn't appear so - overflow interrupts can be enabled or disabled,
but it doesn't appear that there's a way to poll whether the timer has
expired. It doesn't look like it can be inferred either as the counter
status register doesn't stick at zero, rather resets back to the reload
register value (and my interpretation is it continues to count down if
the enabled bit remains set). Further, the interrupt on overflow bit
doesn't appear to be set by the kernel driver, but the two match
registers are initialised to zero which ensures an interrupt will be
fired. Non-zero match registers aren't currently supported by the
device model. I'll try to make this all clearer in the code.

> 
> > 
> > > 
> > > You should implement a VMState struct for device migration,
> > > and wire it up here via dc->vmsd.
> > I'll look into it. I started experimenting with a VMState struct
> > early on in the implementation but threw it away as it wasn't my
> > primary focus at the time.
> We insist on vmstate structs for all new devices, because
> they're fairly easy to implement, and if the original
> submitter doesn't implement one then the device becomes
> a landmine for any user trying migration or vmstate snapshots,
> because it will silently misbehave.

Yeah, no worries, v3 of the series will have VMState structs for all
devices.

Cheers,

Andrew

> 
> thanks
> -- PMM


signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [Qemu-arm] [PATCH v2 1/3] hw/timer: Add ASPEED AST2400 timer device model

2016-02-25 Thread Andrew Jeffery
Hi Peter,

On Thu, 2016-02-25 at 16:11 +, Peter Maydell wrote:
> On 16 February 2016 at 11:34, Andrew Jeffery <and...@aj.id.au> wrote:
> > Implement basic AST2400 timer functionality: Timers can be configured,
> > enabled, reset and disabled.
> > 
> > A number of hardware features are not implemented:
> > 
> > * Timer Overflow interrupts
> > * Clock value matching
> > * Pulse generation
> > 
> > The implementation is enough to boot the Linux kernel configured with
> > aspeed_defconfig.
> 
> Thanks; this mostly looks in reasonable shape; I have some comments below.
> 
> Do we have a datasheet for this chip ?

Unfortunately I don't know of a publicly available datasheet. What's the best 
way to proceed in this case?

> 
> > 
> > Signed-off-by: Andrew Jeffery <and...@aj.id.au>
> > ---
> >  default-configs/arm-softmmu.mak |   2 +
> >  hw/timer/Makefile.objs  |   2 +
> >  hw/timer/aspeed_timer.c | 313 
> > 
> >  include/hw/timer/aspeed_timer.h |  55 +++
> >  trace-events|   9 ++
> >  5 files changed, 381 insertions(+)
> >  create mode 100644 hw/timer/aspeed_timer.c
> >  create mode 100644 include/hw/timer/aspeed_timer.h
> > 
> > diff --git a/default-configs/arm-softmmu.mak 
> > b/default-configs/arm-softmmu.mak
> > index a9f82a1..4072174 100644
> > --- a/default-configs/arm-softmmu.mak
> > +++ b/default-configs/arm-softmmu.mak
> > @@ -110,3 +110,5 @@ CONFIG_IOH3420=y
> >  CONFIG_I82801B11=y
> >  CONFIG_ACPI=y
> >  CONFIG_SMBIOS=y
> > +
> > +CONFIG_ASPEED_SOC=y
> > diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
> > index 133bd0d..f6f7351 100644
> > --- a/hw/timer/Makefile.objs
> > +++ b/hw/timer/Makefile.objs
> > @@ -33,3 +33,5 @@ obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
> >  obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
> > 
> >  common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
> > +
> > +common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
> > diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
> > new file mode 100644
> > index 000..0359528
> > --- /dev/null
> > +++ b/hw/timer/aspeed_timer.c
> > @@ -0,0 +1,313 @@
> > +/*
> > + *  ASPEED AST2400 Timer
> > + *
> > + *  Andrew Jeffery <and...@aj.id.au>
> > + *
> > + *  Copyright (C) 2015, 2016 IBM Corp.
> > + *
> > + *  This program is free software; you can redistribute it and/or modify
> > + *  it under the terms of the GNU General Public License as published by
> > + *  the Free Software Foundation; either version 2 of the License, or
> > + *  (at your option) any later version.
> > + *
> > + *  This program is distributed in the hope that it will be useful,
> > + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + *  GNU General Public License for more details.
> > + *
> > + *  You should have received a copy of the GNU General Public License along
> > + *  with this program; if not, write to the Free Software Foundation, Inc.,
> > + *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include "hw/sysbus.h"
> > +#include "qemu/timer.h"
> > +#include "qemu-common.h"
> > +#include "hw/ptimer.h"
> > +#include "qemu/main-loop.h"
> > +#include "hw/timer/aspeed_timer.h"
> > +#include "trace.h"
> 
> All source files need to #include "qemu/osdep.h" as their first
> include. That then means you don't need to include assert.h or
> stdio.h yourself.
> 
> What do we need from qemu/main-loop.h?

I'm using it for qemu_bh_new() which is required by ptimer, who registers the 
aspeed_timer_tick() callback into the main loop timer handling. I think this 
callback has a poorly chosen name - it's probably better called 
aspeed_timer_expire(), which I'll fix. ptimer seemed like a logical choice for 
implementing the functionality to me, so main-loop.h is required?

> > +#define TIMER_NR_REGS 4
> > +
> > +#define TIMER_CTRL_BITS 4
> > +
> > +#define TIMER_CLOCK_USE_EXT true
> > +#define TIMER_CLOCK_EXT_HZ 100
> > +#define TIMER_CLOCK_USE_APB false
> > +#define TIMER_CLOCK_APB_HZ 2400
> > +
> > +#define TIMER_CTRL_OP_ENABLE 0
> > +#define TIMER_CTRL_OP_CLOCK_SELECT 1
> > +#define TIMER_CTRL_OP_OVERFLOW_INTERR

<    1   2   3   4   >