[PATCH qemu 10/12] ast2400: add a BT device

Andrew Jeffery andrew at aj.id.au
Tue Jun 7 17:15:35 AEST 2016


On Sun, 2016-05-29 at 23:20 +0200, Cédric Le Goater wrote:
> This is an dummy empty shell for the moment. The plan would be to plug
> this device in the IPMI framework already available in qemu and work
> on a backend to connect it to an external host (a powernv guest) or a
> ipmi-host simulator.
> 
> Signed-off-by: Cédric Le Goater <clg at kaod.org>
> ---
>  hw/arm/ast2400.c            |  17 +++++
>  hw/misc/Makefile.objs       |   2 +-
>  hw/misc/aspeed_bt.c         | 175 ++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/arm/ast2400.h    |   2 +
>  include/hw/misc/aspeed_bt.h |  31 ++++++++
>  5 files changed, 226 insertions(+), 1 deletion(-)
>  create mode 100644 hw/misc/aspeed_bt.c
>  create mode 100644 include/hw/misc/aspeed_bt.h
> 
> diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
> index 8f678983cee5..a4a7c10e4361 100644
> --- a/hw/arm/ast2400.c
> +++ b/hw/arm/ast2400.c
> @@ -29,6 +29,8 @@
>  #define AST2400_VIC_BASE         0x1E6C0000
>  #define AST2400_SCU_BASE         0x1E6E2000
>  #define AST2400_TIMER_BASE       0x1E782000
> +#define AST2400_LPC_BASE         0x1E789000
> +#define AST2400_IBT_BASE         (AST2400_LPC_BASE + 0x140)
>  #define AST2400_I2C_BASE         0x1E78A000
>  
>  static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
> @@ -88,6 +90,11 @@ static void ast2400_init(Object *obj)
>      object_initialize(&s->spi, sizeof(s->spi), TYPE_ASPEED_SMC);
>      object_property_add_child(obj, "spi", OBJECT(&s->spi), NULL);
>      qdev_set_parent_bus(DEVICE(&s->spi), sysbus_get_default());
> +     qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
> +
> +    object_initialize(&s->bt, sizeof(s->bt), TYPE_ASPEED_BT);
> +    object_property_add_child(obj, "bt", OBJECT(&s->bt), NULL);
> +    qdev_set_parent_bus(DEVICE(&s->bt), sysbus_get_default());
>  }
>  
>  static void ast2400_realize(DeviceState *dev, Error **errp)
> @@ -204,6 +211,16 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>      sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, AST2400_SPI_BASE);
> +
> +    /* iBT */
> +    object_property_set_bool(OBJECT(&s->bt), true, "realized", &err);
> +    if (err) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->bt), 0, AST2400_IBT_BASE);
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->bt), 0,
> +                       qdev_get_gpio_in(DEVICE(&s->vic), 10));
>  }
>  
>  static void ast2400_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index e50596965b03..b2931f85f097 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -51,4 +51,4 @@ obj-$(CONFIG_MIPS_ITU) += mips_itu.o
>  obj-$(CONFIG_PVPANIC) += pvpanic.o
>  obj-$(CONFIG_EDU) += edu.o
>  obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
> -obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
> +obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_bt.o
> diff --git a/hw/misc/aspeed_bt.c b/hw/misc/aspeed_bt.c
> new file mode 100644
> index 000000000000..496c9aa0be4a
> --- /dev/null
> +++ b/hw/misc/aspeed_bt.c
> @@ -0,0 +1,175 @@
> +/*
> + * ASPEED iBT Device
> + *
> + * 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_bt.h"
> +#include "hw/qdev-properties.h"
> +#include "qemu/bitops.h"
> +#include "trace.h"
> +
> +#ifdef ASPEED_BT_DEBUG
> +#define DB_PRINT(fmt, ...) do {         \
> +        fprintf(stderr,  "%s: " fmt, __func__, ## __VA_ARGS__);  \
> +    } while (0);
> +#else
> +    #define DB_PRINT(...) do {} while (0)
> +#endif

If they're worth keeping should we switch to trace events?

> +
> +#define BT_IO_REGION_SIZE 0x1C
> +
> +#define TO_REG(o) (o >> 2)
> +
> +#define BT_CR0                0x0
> +#define   BT_CR0_IO_BASE         16
> +#define   BT_CR0_IRQ             12

How were you planning to use BT_CR0_IO_BASE and BT_CR0_IRQ? They don't
seem to correspond to obvious fields in CR0. They don't appear to be
used by the code though.

> +#define   BT_CR0_EN_CLR_SLV_RDP  0x8
> +#define   BT_CR0_EN_CLR_SLV_WRP  0x4
> +#define   BT_CR0_ENABLE_IBT      0x1
> +#define BT_CR1                0x4
> +#define   BT_CR1_IRQ_H2B         0x01
> +#define   BT_CR1_IRQ_HBUSY       0x40
> +#define BT_CR2                0x8
> +#define   BT_CR2_IRQ_H2B         0x01
> +#define   BT_CR2_IRQ_HBUSY       0x40
> +#define BT_CR3                0xc
> +#define BT_CTRL                  0x10

The alignment of the value is a bit misleading - indented too far?

> +#define   BT_CTRL_B_BUSY         0x80
> +#define   BT_CTRL_H_BUSY         0x40
> +#define   BT_CTRL_OEM0           0x20
> +#define   BT_CTRL_SMS_ATN        0x10
> +#define   BT_CTRL_B2H_ATN        0x08
> +#define   BT_CTRL_H2B_ATN        0x04
> +#define   BT_CTRL_CLR_RD_PTR     0x02
> +#define   BT_CTRL_CLR_WR_PTR     0x01
> +#define BT_BMC2HOST            0x14
> +#define BT_INTMASK             0x18
> +#define   BT_INTMASK_B2H_IRQEN   0x01
> +#define   BT_INTMASK_B2H_IRQ     0x02
> +#define   BT_INTMASK_BMC_HWRST   0x80
> +
> +static uint64_t aspeed_bt_read(void *opaque, hwaddr offset, unsigned size)
> +{
> +    AspeedBTState *s = ASPEED_BT(opaque);
> +
> +    DB_PRINT("To 0x%" HWADDR_PRIx " of size %u\n", offset, size);
> +
> +    if (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 0x00 ... 0x18:
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP,
> +                      "%s: Read from uninitialised register 0x%"
> +                      HWADDR_PRIx "\n", __func__, offset);
> +        break;
> +    }
> +
> +    return s->regs[TO_REG(offset)];
> +}
> +
> +static void aspeed_bt_write(void *opaque, hwaddr offset, uint64_t data,
> +                             unsigned size)
> +{
> +    AspeedBTState *s = ASPEED_BT(opaque);
> +
> +    DB_PRINT("To 0x%" HWADDR_PRIx " of size %u: 0x%" PRIx64"\n",
> +             offset, size, data);
> +
> +    if (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;
> +    }
> +
> +    switch (offset) {
> +    case 0x00 ... 0x18:
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP,
> +                      "%s: Write to uninitialised register 0x%"
> +                      HWADDR_PRIx "\n", __func__, offset);
> +        break;
> +    }
> +
> +    s->regs[TO_REG(offset)] = (uint32_t) data;
> +}
> +
> +static const MemoryRegionOps aspeed_bt_ops = {
> +    .read = aspeed_bt_read,
> +    .write = aspeed_bt_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +    .valid.min_access_size = 4,
> +    .valid.max_access_size = 4,
> +    .valid.unaligned = false,
> +};
> +
> +static void aspeed_bt_reset(DeviceState *dev)
> +{
> +    AspeedBTState *s = ASPEED_BT(dev);
> +
> +    memset(s->regs, 0, sizeof(s->regs));
> +}
> +
> +static void aspeed_bt_realize(DeviceState *dev, Error **errp)
> +{
> +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> +    AspeedBTState *s = ASPEED_BT(dev);
> +
> +    sysbus_init_irq(sbd, &s->irq);
> +    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_bt_ops, s,
> +                          TYPE_ASPEED_BT, BT_IO_REGION_SIZE);
> +
> +    sysbus_init_mmio(sbd, &s->iomem);
> +}
> +
> +static Property aspeed_bt_props[] = {
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static const VMStateDescription vmstate_aspeed_bt = {
> +    .name = "aspeed.bt",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT32_ARRAY(regs, AspeedBTState, ASPEED_BT_NR_REGS),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static void aspeed_bt_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    dc->realize = aspeed_bt_realize;
> +    dc->reset = aspeed_bt_reset;
> +    dc->desc = "ASPEED iBT Device";
> +    dc->vmsd = &vmstate_aspeed_bt;
> +    dc->props = aspeed_bt_props;
> +}
> +
> +static const TypeInfo aspeed_bt_info = {
> +    .name = TYPE_ASPEED_BT,
> +    .parent = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(AspeedBTState),
> +    .class_init = aspeed_bt_class_init,
> +};
> +
> +static void aspeed_bt_register_types(void)
> +{
> +    type_register_static(&aspeed_bt_info);
> +}
> +
> +type_init(aspeed_bt_register_types);
> diff --git a/include/hw/arm/ast2400.h b/include/hw/arm/ast2400.h
> index 9ba4245619c1..2b517e89eeea 100644
> --- a/include/hw/arm/ast2400.h
> +++ b/include/hw/arm/ast2400.h
> @@ -18,6 +18,7 @@
>  #include "hw/timer/aspeed_timer.h"
>  #include "hw/i2c/aspeed_i2c.h"
>  #include "hw/ssi/aspeed_smc.h"
> +#include "hw/misc/aspeed_bt.h"
>  
>  typedef struct AST2400State {
>      /*< private >*/
> @@ -33,6 +34,7 @@ typedef struct AST2400State {
>      AspeedI2CState i2c;
>      AspeedSMCState smc;
>      AspeedSMCState spi;
> +    AspeedBTState bt;
>  } AST2400State;
>  
>  #define TYPE_AST2400 "ast2400"
> diff --git a/include/hw/misc/aspeed_bt.h b/include/hw/misc/aspeed_bt.h
> new file mode 100644
> index 000000000000..1e9aa9510959
> --- /dev/null
> +++ b/include/hw/misc/aspeed_bt.h
> @@ -0,0 +1,31 @@
> +/*
> + * ASPEED iBT Device
> + *
> + * Copyright 2016 IBM Corp.
> + *
> + * This code is licensed under the GPL version 2 or later.  See
> + * the COPYING file in the top-level directory.
> + */
> +#ifndef ASPEED_BT_H
> +#define ASPEED_BT_H
> +
> +#include "hw/sysbus.h"
> +
> +#define TYPE_ASPEED_BT "aspeed.bt"
> +#define ASPEED_BT(obj) OBJECT_CHECK(AspeedBTState, (obj), TYPE_ASPEED_BT)
> +
> +#define ASPEED_BT_NR_REGS (0x1C >> 2)
> +
> +typedef struct AspeedBTState {
> +    /*< private >*/
> +    SysBusDevice parent_obj;
> +
> +    /*< public >*/
> +    MemoryRegion iomem;
> +    qemu_irq irq;
> +
> +    uint32_t regs[ASPEED_BT_NR_REGS];
> +
> +} AspeedBTState;
> +
> +#endif /* ASPEED_BT_H */

Cheers,

Andrew
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.ozlabs.org/pipermail/openbmc/attachments/20160607/7e700673/attachment.sig>


More information about the openbmc mailing list