qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Qemu-devel] [PATCH] Implement RCC2 in Stellaris


From: Krumme, Chris
Subject: RE: [Qemu-devel] [PATCH] Implement RCC2 in Stellaris
Date: Thu, 13 Aug 2009 20:34:00 -0700

 

> -----Original Message-----
> From: 
> address@hidden 
> [mailto:address@hidden
> rg] On Behalf Of Vijay Kumar
> Sent: Thursday, August 13, 2009 7:10 AM
> To: address@hidden
> Cc: address@hidden
> Subject: [Qemu-devel] [PATCH] Implement RCC2 in Stellaris
> 
> Code from Stellarisware fails to execute in qemu, since it tries to
> read/write to RCC2, that is not available in the Sandstorm register
> interface. But the Stellarisware code assumes that the processor
> ignores writes to RCC2 and reads return 0. This patch implements the
> RCC2 register, which provides the required behaviour in the Fury and
> Sandstorm interface.
> 
>   * Added RCC2 register in the SYSCTL block.
>   * Moved Sandstorm and Fury identification helper functions.
>   * Save and restore RCC2.
> 
> Signed-off-by: Vijay Kumar B. <address@hidden>
> 
> diff --git a/hw/stellaris.c b/hw/stellaris.c
> index d9434ca..1de53ee 100644
> --- a/hw/stellaris.c
> +++ b/hw/stellaris.c
> @@ -7,6 +7,8 @@
>   * This code is licenced under the GPL.
>   */
>  
> +#include <stdbool.h>
> +
>  #include "sysbus.h"
>  #include "ssi.h"
>  #include "arm-misc.h"
> @@ -367,6 +369,7 @@ typedef struct {
>      uint32_t int_mask;
>      uint32_t resc;
>      uint32_t rcc;
> +    uint32_t rcc2;
>      uint32_t rcgc[3];
>      uint32_t scgc[3];
>      uint32_t dcgc[3];
> @@ -421,6 +424,36 @@ static uint32_t pllcfg_fury[16] = {
>      0xb11c /* 8.192 Mhz */
>  };
>  
> +#define DID0_VER_MASK        0x70000000
> +#define DID0_VER_0           0x00000000
> +#define DID0_VER_1           0x10000000
> +
> +#define DID0_CLASS_MASK      0x00FF0000
> +#define DID0_CLASS_SANDSTORM 0x00000000
> +#define DID0_CLASS_FURY      0x00010000
> +
> +static bool ssys_is_sandstorm(ssys_state *s)
> +{
> +    uint32_t did0 = s->board->did0;
> +
> +    switch (did0 & DID0_VER_MASK) {
> +    case DID0_VER_0:
> +     return 1;
> +    case DID0_VER_1:
> +     return ((did0 & DID0_CLASS_MASK) == DID0_CLASS_SANDSTORM);
> +    default:
> +     return 0;
> +    }
> +}
> +
> +static bool ssys_is_fury(ssys_state *s)
> +{
> +    uint32_t did0 = s->board->did0;
> +
> +    return (((did0 & DID0_VER_MASK) == DID0_VER_1)
> +         && ((did0 & DID0_CLASS_MASK) == DID0_CLASS_FURY));
> +}
> +
>  static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
>  {
>      ssys_state *s = (ssys_state *)opaque;
> @@ -464,12 +497,14 @@ static uint32_t ssys_read(void *opaque, 
> target_phys_addr_t offset)
>          {
>              int xtal;
>              xtal = (s->rcc >> 6) & 0xf;
> -            if (s->board->did0 & (1 << 16)) {
> +            if (ssys_is_fury(s)) {
>                  return pllcfg_fury[xtal];
>              } else {
>                  return pllcfg_sandstorm[xtal];
>              }
>          }
> +    case 0x070: /* RCC2 */
> +        return s->rcc2;
>      case 0x100: /* RCGC0 */
>          return s->rcgc[0];
>      case 0x104: /* RCGC1 */
> @@ -502,9 +537,21 @@ static uint32_t ssys_read(void *opaque, 
> target_phys_addr_t offset)
>      }
>  }
>  
> +static bool ssys_use_rcc2(ssys_state *s)
> +{
> +    return (s->rcc2 >> 31) & 0x1;
> +}
> +
> +/* 
> + * Caculate the sys. clock period in ms.
> + */
>  static void ssys_calculate_system_clock(ssys_state *s)
>  {
> -    system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
> +    if (ssys_use_rcc2(s)) {
> +     system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
> +    } else {
> +     system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
> +    }
>  }
>  
>  static void ssys_write(void *opaque, target_phys_addr_t 
> offset, uint32_t value)
> @@ -540,6 +587,17 @@ static void ssys_write(void *opaque, 
> target_phys_addr_t offset, uint32_t value)
>          s->rcc = value;
>          ssys_calculate_system_clock(s);
>          break;
> +    case 0x070: /* RCC2 */
> +        if (ssys_is_sandstorm(s))
> +         break;
> +
> +        if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
> +            /* PLL enable.  */
> +            s->int_status |= (1 << 6);
> +        }
> +     s->rcc2 = value;
> +     ssys_calculate_system_clock(s);
> +     break;
>      case 0x100: /* RCGC0 */
>          s->rcgc[0] = value;
>          break;
> @@ -597,6 +655,12 @@ static void ssys_reset(void *opaque)
>  
>      s->pborctl = 0x7ffd;
>      s->rcc = 0x078e3ac0;
> +
> +    if (ssys_is_sandstorm(s))
> +     s->rcc2 = 0;
> +    else
> +     s->rcc2 = 0x07802810;
> +
>      s->rcgc[0] = 1;
>      s->scgc[0] = 1;
>      s->dcgc[0] = 1;
> @@ -612,6 +676,7 @@ static void ssys_save(QEMUFile *f, void *opaque)
>      qemu_put_be32(f, s->int_status);
>      qemu_put_be32(f, s->resc);
>      qemu_put_be32(f, s->rcc);
> +    qemu_put_be32(f, s->rcc2);
>      qemu_put_be32(f, s->rcgc[0]);
>      qemu_put_be32(f, s->rcgc[1]);
>      qemu_put_be32(f, s->rcgc[2]);
> @@ -629,7 +694,7 @@ static int ssys_load(QEMUFile *f, void 
> *opaque, int version_id)
>  {
>      ssys_state *s = (ssys_state *)opaque;
>  
> -    if (version_id != 1)
> +    if (version_id != 2)
>          return -EINVAL;
>  
>      s->pborctl = qemu_get_be32(f);
> @@ -638,6 +703,7 @@ static int ssys_load(QEMUFile *f, void 
> *opaque, int version_id)
>      s->int_status = qemu_get_be32(f);
>      s->resc = qemu_get_be32(f);
>      s->rcc = qemu_get_be32(f);
> +    s->rcc2 = qemu_get_be32(f);

If I understand correctly this should be protected by an if (version ==
2), and the if above should support both 1 and 2.

This does not seem like a change that should break old --> new
migration.

There are examples in other modules.

Hope this helps.

Chris


>      s->rcgc[0] = qemu_get_be32(f);
>      s->rcgc[1] = qemu_get_be32(f);
>      s->rcgc[2] = qemu_get_be32(f);
> @@ -672,7 +738,7 @@ static void stellaris_sys_init(uint32_t 
> base, qemu_irq irq,
>                                         ssys_writefn, s);
>      cpu_register_physical_memory(base, 0x00001000, iomemtype);
>      ssys_reset(s);
> -    register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s);
> +    register_savevm("stellaris_sys", -1, 2, ssys_save, ssys_load, s);
>  }
>  
>  
> 
> 
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]