mirror of https://gitee.com/openkylin/qemu.git
bcm2835_aux: add emulation of BCM2835 AUX (aka UART1) block
At present only the core UART functions (data path for tx/rx) are implemented, which is enough for UEFI to boot. The following features/registers are unimplemented: * Line/modem control * Scratch register * Extra control * Baudrate * SPI interfaces Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1457467526-8840-3-git-send-email-Andrew.Baumann@microsoft.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a2a8dfa8d8
commit
97398d900c
|
@ -12,6 +12,7 @@
|
||||||
#include "hw/arm/bcm2835_peripherals.h"
|
#include "hw/arm/bcm2835_peripherals.h"
|
||||||
#include "hw/misc/bcm2835_mbox_defs.h"
|
#include "hw/misc/bcm2835_mbox_defs.h"
|
||||||
#include "hw/arm/raspi_platform.h"
|
#include "hw/arm/raspi_platform.h"
|
||||||
|
#include "sysemu/char.h"
|
||||||
|
|
||||||
/* Peripheral base address on the VC (GPU) system bus */
|
/* Peripheral base address on the VC (GPU) system bus */
|
||||||
#define BCM2835_VC_PERI_BASE 0x7e000000
|
#define BCM2835_VC_PERI_BASE 0x7e000000
|
||||||
|
@ -48,6 +49,11 @@ static void bcm2835_peripherals_init(Object *obj)
|
||||||
object_property_add_child(obj, "uart0", OBJECT(s->uart0), NULL);
|
object_property_add_child(obj, "uart0", OBJECT(s->uart0), NULL);
|
||||||
qdev_set_parent_bus(DEVICE(s->uart0), sysbus_get_default());
|
qdev_set_parent_bus(DEVICE(s->uart0), sysbus_get_default());
|
||||||
|
|
||||||
|
/* AUX / UART1 */
|
||||||
|
object_initialize(&s->aux, sizeof(s->aux), TYPE_BCM2835_AUX);
|
||||||
|
object_property_add_child(obj, "aux", OBJECT(&s->aux), NULL);
|
||||||
|
qdev_set_parent_bus(DEVICE(&s->aux), sysbus_get_default());
|
||||||
|
|
||||||
/* Mailboxes */
|
/* Mailboxes */
|
||||||
object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX);
|
object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX);
|
||||||
object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL);
|
object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL);
|
||||||
|
@ -79,6 +85,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
|
||||||
MemoryRegion *ram;
|
MemoryRegion *ram;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
uint32_t ram_size;
|
uint32_t ram_size;
|
||||||
|
CharDriverState *chr;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
obj = object_property_get_link(OBJECT(dev), "ram", &err);
|
obj = object_property_get_link(OBJECT(dev), "ram", &err);
|
||||||
|
@ -131,6 +138,29 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
|
||||||
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
|
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
|
||||||
INTERRUPT_UART));
|
INTERRUPT_UART));
|
||||||
|
|
||||||
|
/* AUX / UART1 */
|
||||||
|
/* TODO: don't call qemu_char_get_next_serial() here, instead set
|
||||||
|
* chardev properties for each uart at the board level, once pl011
|
||||||
|
* (uart0) has been updated to avoid qemu_char_get_next_serial()
|
||||||
|
*/
|
||||||
|
chr = qemu_char_get_next_serial();
|
||||||
|
if (chr == NULL) {
|
||||||
|
chr = qemu_chr_new("bcm2835.uart1", "null", NULL);
|
||||||
|
}
|
||||||
|
qdev_prop_set_chr(DEVICE(&s->aux), "chardev", chr);
|
||||||
|
|
||||||
|
object_property_set_bool(OBJECT(&s->aux), true, "realized", &err);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_region_add_subregion(&s->peri_mr, UART1_OFFSET,
|
||||||
|
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->aux), 0));
|
||||||
|
sysbus_connect_irq(SYS_BUS_DEVICE(&s->aux), 0,
|
||||||
|
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
|
||||||
|
INTERRUPT_AUX));
|
||||||
|
|
||||||
/* Mailboxes */
|
/* Mailboxes */
|
||||||
object_property_set_bool(OBJECT(&s->mboxes), true, "realized", &err);
|
object_property_set_bool(OBJECT(&s->mboxes), true, "realized", &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -203,6 +233,8 @@ static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
|
||||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||||
|
|
||||||
dc->realize = bcm2835_peripherals_realize;
|
dc->realize = bcm2835_peripherals_realize;
|
||||||
|
/* Reason: realize() method uses qemu_char_get_next_serial() */
|
||||||
|
dc->cannot_instantiate_with_device_add_yet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo bcm2835_peripherals_type_info = {
|
static const TypeInfo bcm2835_peripherals_type_info = {
|
||||||
|
|
|
@ -16,6 +16,7 @@ obj-$(CONFIG_SH4) += sh_serial.o
|
||||||
obj-$(CONFIG_PSERIES) += spapr_vty.o
|
obj-$(CONFIG_PSERIES) += spapr_vty.o
|
||||||
obj-$(CONFIG_DIGIC) += digic-uart.o
|
obj-$(CONFIG_DIGIC) += digic-uart.o
|
||||||
obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
|
obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
|
||||||
|
obj-$(CONFIG_RASPI) += bcm2835_aux.o
|
||||||
|
|
||||||
common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
|
common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
|
||||||
common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
|
common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
|
||||||
|
|
|
@ -0,0 +1,316 @@
|
||||||
|
/*
|
||||||
|
* BCM2835 (Raspberry Pi / Pi 2) Aux block (mini UART and SPI).
|
||||||
|
* Copyright (c) 2015, Microsoft
|
||||||
|
* Written by Andrew Baumann
|
||||||
|
* Based on pl011.c, copyright terms below:
|
||||||
|
*
|
||||||
|
* Arm PrimeCell PL011 UART
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006 CodeSourcery.
|
||||||
|
* Written by Paul Brook
|
||||||
|
*
|
||||||
|
* This code is licensed under the GPL.
|
||||||
|
*
|
||||||
|
* At present only the core UART functions (data path for tx/rx) are
|
||||||
|
* implemented. The following features/registers are unimplemented:
|
||||||
|
* - Line/modem control
|
||||||
|
* - Scratch register
|
||||||
|
* - Extra control
|
||||||
|
* - Baudrate
|
||||||
|
* - SPI interfaces
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "hw/char/bcm2835_aux.h"
|
||||||
|
|
||||||
|
#define AUX_IRQ 0x0
|
||||||
|
#define AUX_ENABLES 0x4
|
||||||
|
#define AUX_MU_IO_REG 0x40
|
||||||
|
#define AUX_MU_IER_REG 0x44
|
||||||
|
#define AUX_MU_IIR_REG 0x48
|
||||||
|
#define AUX_MU_LCR_REG 0x4c
|
||||||
|
#define AUX_MU_MCR_REG 0x50
|
||||||
|
#define AUX_MU_LSR_REG 0x54
|
||||||
|
#define AUX_MU_MSR_REG 0x58
|
||||||
|
#define AUX_MU_SCRATCH 0x5c
|
||||||
|
#define AUX_MU_CNTL_REG 0x60
|
||||||
|
#define AUX_MU_STAT_REG 0x64
|
||||||
|
#define AUX_MU_BAUD_REG 0x68
|
||||||
|
|
||||||
|
/* bits in IER/IIR registers */
|
||||||
|
#define TX_INT 0x1
|
||||||
|
#define RX_INT 0x2
|
||||||
|
|
||||||
|
static void bcm2835_aux_update(BCM2835AuxState *s)
|
||||||
|
{
|
||||||
|
/* signal an interrupt if either:
|
||||||
|
* 1. rx interrupt is enabled and we have a non-empty rx fifo, or
|
||||||
|
* 2. the tx interrupt is enabled (since we instantly drain the tx fifo)
|
||||||
|
*/
|
||||||
|
s->iir = 0;
|
||||||
|
if ((s->ier & RX_INT) && s->read_count != 0) {
|
||||||
|
s->iir |= RX_INT;
|
||||||
|
}
|
||||||
|
if (s->ier & TX_INT) {
|
||||||
|
s->iir |= TX_INT;
|
||||||
|
}
|
||||||
|
qemu_set_irq(s->irq, s->iir != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
|
||||||
|
{
|
||||||
|
BCM2835AuxState *s = opaque;
|
||||||
|
uint32_t c, res;
|
||||||
|
|
||||||
|
switch (offset) {
|
||||||
|
case AUX_IRQ:
|
||||||
|
return s->iir != 0;
|
||||||
|
|
||||||
|
case AUX_ENABLES:
|
||||||
|
return 1; /* mini UART permanently enabled */
|
||||||
|
|
||||||
|
case AUX_MU_IO_REG:
|
||||||
|
/* "DLAB bit set means access baudrate register" is NYI */
|
||||||
|
c = s->read_fifo[s->read_pos];
|
||||||
|
if (s->read_count > 0) {
|
||||||
|
s->read_count--;
|
||||||
|
if (++s->read_pos == BCM2835_AUX_RX_FIFO_LEN) {
|
||||||
|
s->read_pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s->chr) {
|
||||||
|
qemu_chr_accept_input(s->chr);
|
||||||
|
}
|
||||||
|
bcm2835_aux_update(s);
|
||||||
|
return c;
|
||||||
|
|
||||||
|
case AUX_MU_IER_REG:
|
||||||
|
/* "DLAB bit set means access baudrate register" is NYI */
|
||||||
|
return 0xc0 | s->ier; /* FIFO enables always read 1 */
|
||||||
|
|
||||||
|
case AUX_MU_IIR_REG:
|
||||||
|
res = 0xc0; /* FIFO enables */
|
||||||
|
/* The spec is unclear on what happens when both tx and rx
|
||||||
|
* interrupts are active, besides that this cannot occur. At
|
||||||
|
* present, we choose to prioritise the rx interrupt, since
|
||||||
|
* the tx fifo is always empty. */
|
||||||
|
if (s->read_count != 0) {
|
||||||
|
res |= 0x4;
|
||||||
|
} else {
|
||||||
|
res |= 0x2;
|
||||||
|
}
|
||||||
|
if (s->iir == 0) {
|
||||||
|
res |= 0x1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
|
||||||
|
case AUX_MU_LCR_REG:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_LCR_REG unsupported\n", __func__);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case AUX_MU_MCR_REG:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_MCR_REG unsupported\n", __func__);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case AUX_MU_LSR_REG:
|
||||||
|
res = 0x60; /* tx idle, empty */
|
||||||
|
if (s->read_count != 0) {
|
||||||
|
res |= 0x1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
|
||||||
|
case AUX_MU_MSR_REG:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_MSR_REG unsupported\n", __func__);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case AUX_MU_SCRATCH:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_SCRATCH unsupported\n", __func__);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case AUX_MU_CNTL_REG:
|
||||||
|
return 0x3; /* tx, rx enabled */
|
||||||
|
|
||||||
|
case AUX_MU_STAT_REG:
|
||||||
|
res = 0x30e; /* space in the output buffer, empty tx fifo, idle tx/rx */
|
||||||
|
if (s->read_count > 0) {
|
||||||
|
res |= 0x1; /* data in input buffer */
|
||||||
|
assert(s->read_count < BCM2835_AUX_RX_FIFO_LEN);
|
||||||
|
res |= ((uint32_t)s->read_count) << 16; /* rx fifo fill level */
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
|
||||||
|
case AUX_MU_BAUD_REG:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_BAUD_REG unsupported\n", __func__);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
|
||||||
|
__func__, offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
|
||||||
|
unsigned size)
|
||||||
|
{
|
||||||
|
BCM2835AuxState *s = opaque;
|
||||||
|
unsigned char ch;
|
||||||
|
|
||||||
|
switch (offset) {
|
||||||
|
case AUX_ENABLES:
|
||||||
|
if (value != 1) {
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: unsupported attempt to enable SPI "
|
||||||
|
"or disable UART\n", __func__);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUX_MU_IO_REG:
|
||||||
|
/* "DLAB bit set means access baudrate register" is NYI */
|
||||||
|
ch = value;
|
||||||
|
if (s->chr) {
|
||||||
|
qemu_chr_fe_write(s->chr, &ch, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUX_MU_IER_REG:
|
||||||
|
/* "DLAB bit set means access baudrate register" is NYI */
|
||||||
|
s->ier = value & (TX_INT | RX_INT);
|
||||||
|
bcm2835_aux_update(s);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUX_MU_IIR_REG:
|
||||||
|
if (value & 0x2) {
|
||||||
|
s->read_count = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUX_MU_LCR_REG:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_LCR_REG unsupported\n", __func__);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUX_MU_MCR_REG:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_MCR_REG unsupported\n", __func__);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUX_MU_SCRATCH:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_SCRATCH unsupported\n", __func__);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUX_MU_CNTL_REG:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_CNTL_REG unsupported\n", __func__);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUX_MU_BAUD_REG:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_BAUD_REG unsupported\n", __func__);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
|
||||||
|
__func__, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bcm2835_aux_update(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bcm2835_aux_can_receive(void *opaque)
|
||||||
|
{
|
||||||
|
BCM2835AuxState *s = opaque;
|
||||||
|
|
||||||
|
return s->read_count < BCM2835_AUX_RX_FIFO_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bcm2835_aux_put_fifo(void *opaque, uint8_t value)
|
||||||
|
{
|
||||||
|
BCM2835AuxState *s = opaque;
|
||||||
|
int slot;
|
||||||
|
|
||||||
|
slot = s->read_pos + s->read_count;
|
||||||
|
if (slot >= BCM2835_AUX_RX_FIFO_LEN) {
|
||||||
|
slot -= BCM2835_AUX_RX_FIFO_LEN;
|
||||||
|
}
|
||||||
|
s->read_fifo[slot] = value;
|
||||||
|
s->read_count++;
|
||||||
|
if (s->read_count == BCM2835_AUX_RX_FIFO_LEN) {
|
||||||
|
/* buffer full */
|
||||||
|
}
|
||||||
|
bcm2835_aux_update(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, int size)
|
||||||
|
{
|
||||||
|
bcm2835_aux_put_fifo(opaque, *buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const MemoryRegionOps bcm2835_aux_ops = {
|
||||||
|
.read = bcm2835_aux_read,
|
||||||
|
.write = bcm2835_aux_write,
|
||||||
|
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||||
|
.valid.min_access_size = 4,
|
||||||
|
.valid.max_access_size = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_bcm2835_aux = {
|
||||||
|
.name = TYPE_BCM2835_AUX,
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_UINT8_ARRAY(read_fifo, BCM2835AuxState,
|
||||||
|
BCM2835_AUX_RX_FIFO_LEN),
|
||||||
|
VMSTATE_UINT8(read_pos, BCM2835AuxState),
|
||||||
|
VMSTATE_UINT8(read_count, BCM2835AuxState),
|
||||||
|
VMSTATE_UINT8(ier, BCM2835AuxState),
|
||||||
|
VMSTATE_UINT8(iir, BCM2835AuxState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void bcm2835_aux_init(Object *obj)
|
||||||
|
{
|
||||||
|
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||||
|
BCM2835AuxState *s = BCM2835_AUX(obj);
|
||||||
|
|
||||||
|
memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_aux_ops, s,
|
||||||
|
TYPE_BCM2835_AUX, 0x100);
|
||||||
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
|
sysbus_init_irq(sbd, &s->irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bcm2835_aux_realize(DeviceState *dev, Error **errp)
|
||||||
|
{
|
||||||
|
BCM2835AuxState *s = BCM2835_AUX(dev);
|
||||||
|
|
||||||
|
if (s->chr) {
|
||||||
|
qemu_chr_add_handlers(s->chr, bcm2835_aux_can_receive,
|
||||||
|
bcm2835_aux_receive, NULL, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Property bcm2835_aux_props[] = {
|
||||||
|
DEFINE_PROP_CHR("chardev", BCM2835AuxState, chr),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void bcm2835_aux_class_init(ObjectClass *oc, void *data)
|
||||||
|
{
|
||||||
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||||
|
|
||||||
|
dc->realize = bcm2835_aux_realize;
|
||||||
|
dc->vmsd = &vmstate_bcm2835_aux;
|
||||||
|
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
|
||||||
|
dc->props = bcm2835_aux_props;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo bcm2835_aux_info = {
|
||||||
|
.name = TYPE_BCM2835_AUX,
|
||||||
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
|
.instance_size = sizeof(BCM2835AuxState),
|
||||||
|
.instance_init = bcm2835_aux_init,
|
||||||
|
.class_init = bcm2835_aux_class_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void bcm2835_aux_register_types(void)
|
||||||
|
{
|
||||||
|
type_register_static(&bcm2835_aux_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
type_init(bcm2835_aux_register_types)
|
|
@ -14,6 +14,7 @@
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
|
#include "hw/char/bcm2835_aux.h"
|
||||||
#include "hw/intc/bcm2835_ic.h"
|
#include "hw/intc/bcm2835_ic.h"
|
||||||
#include "hw/misc/bcm2835_property.h"
|
#include "hw/misc/bcm2835_property.h"
|
||||||
#include "hw/misc/bcm2835_mbox.h"
|
#include "hw/misc/bcm2835_mbox.h"
|
||||||
|
@ -33,6 +34,7 @@ typedef struct BCM2835PeripheralState {
|
||||||
qemu_irq irq, fiq;
|
qemu_irq irq, fiq;
|
||||||
|
|
||||||
SysBusDevice *uart0;
|
SysBusDevice *uart0;
|
||||||
|
BCM2835AuxState aux;
|
||||||
BCM2835ICState ic;
|
BCM2835ICState ic;
|
||||||
BCM2835PropertyState property;
|
BCM2835PropertyState property;
|
||||||
BCM2835MboxState mboxes;
|
BCM2835MboxState mboxes;
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
|
||||||
|
* Written by Andrew Baumann
|
||||||
|
*
|
||||||
|
* This code is licensed under the GNU GPLv2 and later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BCM2835_AUX_H
|
||||||
|
#define BCM2835_AUX_H
|
||||||
|
|
||||||
|
#include "hw/sysbus.h"
|
||||||
|
#include "sysemu/char.h"
|
||||||
|
|
||||||
|
#define TYPE_BCM2835_AUX "bcm2835-aux"
|
||||||
|
#define BCM2835_AUX(obj) OBJECT_CHECK(BCM2835AuxState, (obj), TYPE_BCM2835_AUX)
|
||||||
|
|
||||||
|
#define BCM2835_AUX_RX_FIFO_LEN 8
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/*< private >*/
|
||||||
|
SysBusDevice parent_obj;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
MemoryRegion iomem;
|
||||||
|
CharDriverState *chr;
|
||||||
|
qemu_irq irq;
|
||||||
|
|
||||||
|
uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN];
|
||||||
|
uint8_t read_pos, read_count;
|
||||||
|
uint8_t ier, iir;
|
||||||
|
} BCM2835AuxState;
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue