From 428a0ea8bfa45b354819f4f19da2e58f68dc7dd1 Mon Sep 17 00:00:00 2001 From: Andrew Baumann Date: Mon, 28 Dec 2015 10:46:23 -0800 Subject: [PATCH] pi: cross-port refactoring/cleanup from private branch used for ongoing upstreaming major changes: * renamed bcm2835_sbm to bcm2835_mbox * dropped bcm2835_arm_control.h * refactored logic in bcm2835_ic and bcm2835_mbox * misc cleanup and coding style tweaks --- hw/arm/Makefile.objs | 2 +- hw/arm/bcm2835_peripherals.c | 105 ++--- hw/display/bcm2835_fb.c | 2 +- hw/intc/bcm2835_ic.c | 467 +++++++++++---------- hw/intc/bcm2836_control.c | 28 +- hw/misc/Makefile.objs | 2 +- hw/misc/bcm2835_mbox.c | 323 +++++++++++++++ hw/misc/bcm2835_power.c | 2 +- hw/misc/bcm2835_property.c | 62 +-- hw/misc/bcm2835_sbm.c | 280 ------------- hw/misc/bcm2835_vchiq.c | 2 +- include/hw/arm/bcm2835_arm_control.h | 481 ---------------------- include/hw/arm/bcm2835_mbox.h | 14 - include/hw/arm/bcm2835_peripherals.h | 6 +- include/hw/arm/raspi_platform.h | 3 +- include/hw/intc/bcm2835_ic.h | 21 +- include/hw/intc/bcm2836_control.h | 2 + include/hw/misc/{bcm2835_sbm.h => bcm2835_mbox.h} | 24 +- include/hw/misc/bcm2835_mbox_defs.h | 26 ++ include/hw/misc/bcm2835_property.h | 4 +- 20 files changed, 732 insertions(+), 1124 deletions(-) mode change 100644 => 100755 hw/arm/Makefile.objs mode change 100644 => 100755 hw/arm/bcm2835_peripherals.c rewrite hw/intc/bcm2835_ic.c (61%) mode change 100644 => 100755 mode change 100644 => 100755 hw/intc/bcm2836_control.c mode change 100644 => 100755 hw/misc/Makefile.objs create mode 100644 hw/misc/bcm2835_mbox.c mode change 100644 => 100755 hw/misc/bcm2835_property.c delete mode 100644 hw/misc/bcm2835_sbm.c delete mode 100644 include/hw/arm/bcm2835_arm_control.h delete mode 100644 include/hw/arm/bcm2835_mbox.h mode change 100644 => 100755 include/hw/arm/bcm2835_peripherals.h mode change 100644 => 100755 include/hw/arm/raspi_platform.h mode change 100644 => 100755 include/hw/intc/bcm2835_ic.h mode change 100644 => 100755 include/hw/intc/bcm2836_control.h rename include/hw/misc/{bcm2835_sbm.h => bcm2835_mbox.h} (55%) create mode 100644 include/hw/misc/bcm2835_mbox_defs.h mode change 100644 => 100755 include/hw/misc/bcm2835_property.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs old mode 100644 new mode 100755 index d48c67e155..ec387d574d --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -11,7 +11,7 @@ obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-$(CONFIG_DIGIC) += digic.o obj-y += omap1.o omap2.o strongarm.o obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o -obj-$(CONFIG_RASPI) += raspi.o bcm2835.o bcm2835_peripherals.o bcm2836.o +obj-$(CONFIG_RASPI) += bcm2835.o bcm2835_peripherals.o bcm2836.o raspi.o 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 diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c old mode 100644 new mode 100755 index 8e7e20d03d..75360ae09a --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -9,7 +9,7 @@ */ #include "hw/arm/bcm2835_peripherals.h" -#include "hw/arm/bcm2835_mbox.h" +#include "hw/misc/bcm2835_mbox_defs.h" #include "hw/arm/raspi_platform.h" /* Capabilities for SD controller: no DMA, high-speed, default clocks etc. */ @@ -72,12 +72,12 @@ static void bcm2835_peripherals_init(Object *obj) object_property_add_child(obj, "mphi", OBJECT(&s->mphi), NULL); qdev_set_parent_bus(DEVICE(&s->mphi), sysbus_get_default()); - /* Semaphores / Doorbells / Mailboxes */ - object_initialize(&s->sbm, sizeof(s->sbm), TYPE_BCM2835_SBM); - object_property_add_child(obj, "sbm", OBJECT(&s->sbm), NULL); - qdev_set_parent_bus(DEVICE(&s->sbm), sysbus_get_default()); + /* Mailboxes */ + object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX); + object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL); + qdev_set_parent_bus(DEVICE(&s->mboxes), sysbus_get_default()); - object_property_add_const_link(OBJECT(&s->sbm), "mbox_mr", + object_property_add_const_link(OBJECT(&s->mboxes), "mbox_mr", OBJECT(&s->mbox_mr), &error_abort); /* Power management */ @@ -175,7 +175,8 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->peri_mr, UART0_OFFSET, sysbus_mmio_get_region(s->uart0, 0)); sysbus_connect_irq(s->uart0, 0, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_VC_UART)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_VC_UART)); /* AUX / UART1 */ object_property_set_bool(OBJECT(&s->aux), true, "realized", &err); @@ -187,7 +188,8 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) 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(DEVICE(&s->ic), INTERRUPT_AUX)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_AUX)); /* System timer */ object_property_set_bool(OBJECT(&s->st), true, "realized", &err); @@ -199,13 +201,17 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->peri_mr, ST_OFFSET, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->st), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 0, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_TIMER0)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_TIMER0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 1, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_TIMER1)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_TIMER1)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 2, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_TIMER2)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_TIMER2)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->st), 3, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_TIMER3)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_TIMER3)); /* ARM timer */ object_property_set_bool(OBJECT(&s->timer), true, "realized", &err); @@ -217,7 +223,8 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->peri_mr, ARMCTRL_TIMER0_1_OFFSET, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer), 0, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_ARM_TIMER)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ, + INTERRUPT_ARM_TIMER - ARM_IRQ0_BASE)); /* XXX */ /* USB controller */ object_property_set_bool(OBJECT(&s->usb), true, "realized", &err); @@ -229,7 +236,8 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->peri_mr, USB_OFFSET, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->usb), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb), 0, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_VC_USB)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_VC_USB)); /* MPHI - Message-based Parallel Host Interface */ object_property_set_bool(OBJECT(&s->mphi), true, "realized", &err); @@ -241,19 +249,21 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->peri_mr, MPHI_OFFSET, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mphi), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->mphi), 0, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_HOSTPORT)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_HOSTPORT)); - /* Semaphores / Doorbells / Mailboxes */ - object_property_set_bool(OBJECT(&s->sbm), true, "realized", &err); + /* Mailboxes */ + object_property_set_bool(OBJECT(&s->mboxes), true, "realized", &err); if (err) { error_propagate(errp, err); return; } memory_region_add_subregion(&s->peri_mr, ARMCTRL_0_SBM_OFFSET, - sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sbm), 0)); - sysbus_connect_irq(SYS_BUS_DEVICE(&s->sbm), 0, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_ARM_MAILBOX)); + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mboxes), 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->mboxes), 0, + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ, + INTERRUPT_ARM_MAILBOX - ARM_IRQ0_BASE)); /* Mailbox-addressable peripherals use the private mbox_mr address space * and pseudo-irqs to dispatch requests and responses. */ @@ -265,10 +275,10 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) return; } - memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_POWER<<4, + memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_POWER << MBOX_AS_CHAN_SHIFT, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->power), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->power), 0, - qdev_get_gpio_in(DEVICE(&s->sbm), MBOX_CHAN_POWER)); + qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_POWER)); /* Framebuffer */ vcram_size = (uint32_t)object_property_get_int(OBJECT(s), "vcram-size", @@ -280,6 +290,10 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->fb), ram_size - vcram_size, "vcram-base", &err); + if (err) { + error_propagate(errp, err); + return; + } object_property_set_bool(OBJECT(&s->fb), true, "realized", &err); if (err) { @@ -287,10 +301,10 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) return; } - memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_FB<<4, + memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_FB << MBOX_AS_CHAN_SHIFT, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->fb), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->fb), 0, - qdev_get_gpio_in(DEVICE(&s->sbm), MBOX_CHAN_FB)); + qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB)); /* Property channel */ object_property_set_bool(OBJECT(&s->property), true, "realized", &err); @@ -299,10 +313,11 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) return; } - memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_PROPERTY<<4, + memory_region_add_subregion(&s->mbox_mr, + MBOX_CHAN_PROPERTY << MBOX_AS_CHAN_SHIFT, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->property), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->property), 0, - qdev_get_gpio_in(DEVICE(&s->sbm), MBOX_CHAN_PROPERTY)); + qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_PROPERTY)); /* VCHIQ */ object_property_set_bool(OBJECT(&s->vchiq), true, "realized", &err); @@ -311,10 +326,10 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) return; } - memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_VCHIQ<<4, + memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_VCHIQ << MBOX_AS_CHAN_SHIFT, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->vchiq), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->vchiq), 0, - qdev_get_gpio_in(DEVICE(&s->sbm), MBOX_CHAN_VCHIQ)); + qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_VCHIQ)); /* Extended Mass Media Controller */ object_property_set_int(OBJECT(&s->sdhci), BCM2835_SDHC_CAPAREG, "capareg", @@ -339,8 +354,8 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->peri_mr, EMMC_OFFSET, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sdhci), 0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, - qdev_get_gpio_in(DEVICE(&s->ic), - INTERRUPT_VC_ARASANSDIO)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, + INTERRUPT_VC_ARASANSDIO)); /* DMA Channels */ object_property_set_bool(OBJECT(&s->dma), true, "realized", &err); @@ -351,37 +366,35 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->peri_mr, DMA_OFFSET, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 0)); - /* XXX: this address was in the original raspi port. - * It's unclear where it is derived from. */ - memory_region_add_subregion(&s->peri_mr, 0xe05000, + memory_region_add_subregion(&s->peri_mr, DMA15_OFFSET, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 1)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 0, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA0)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA0)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 1, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA1)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA1)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 2, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_VC_DMA2)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_VC_DMA2)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 3, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_VC_DMA3)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_VC_DMA3)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 4, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA4)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA4)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 5, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA5)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA5)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 6, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA6)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA6)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 7, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA7)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA7)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 8, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA8)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA8)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 9, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA9)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA9)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 10, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA10)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA10)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 11, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA11)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA11)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), 12, - qdev_get_gpio_in(DEVICE(&s->ic), INTERRUPT_DMA12)); + qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_DMA12)); } static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data) diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index 291fff247c..941df6aa29 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -28,7 +28,7 @@ #include "hw/display/bcm2835_fb.h" #include "hw/display/framebuffer.h" #include "ui/pixel_ops.h" -#include "hw/arm/bcm2835_mbox.h" +#include "hw/misc/bcm2835_mbox_defs.h" #define DEFAULT_VCRAM_SIZE 0x4000000 #define BCM2835_FB_OFFSET 0x00100000 diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c old mode 100644 new mode 100755 dissimilarity index 61% index 2419575f5e..9624e8bc2a --- a/hw/intc/bcm2835_ic.c +++ b/hw/intc/bcm2835_ic.c @@ -1,234 +1,233 @@ -/* - * Raspberry Pi emulation (c) 2012 Gregory Estrade - * This code is licensed under the GNU GPLv2 and later. - */ - -/* Heavily based on pl190.c, copyright terms below. */ - -/* - * Arm PrimeCell PL190 Vector Interrupt Controller - * - * Copyright (c) 2006 CodeSourcery. - * Written by Paul Brook - * - * This code is licensed under the GPL. - */ - -#include "hw/intc/bcm2835_ic.h" - -#define IR_B 2 -#define IR_1 0 -#define IR_2 1 - -/* Update interrupts. */ -static void bcm2835_ic_update(BCM2835IcState *s) -{ - int set; - int i; - - set = 0; - if (s->fiq_enable) { - set = s->level[s->fiq_select >> 5] & (1u << (s->fiq_select & 0x1f)); - } - qemu_set_irq(s->fiq, set); - - set = 0; - for (i = 0; i < 3; i++) { - set |= (s->level[i] & s->irq_enable[i]); - } - qemu_set_irq(s->irq, set); - -} - -static void bcm2835_ic_set_irq(void *opaque, int irq, int level) -{ - BCM2835IcState *s = (BCM2835IcState *)opaque; - - if (irq >= 0 && irq <= 71) { - if (level) { - s->level[irq >> 5] |= 1u << (irq & 0x1f); - } else { - s->level[irq >> 5] &= ~(1u << (irq & 0x1f)); - } - } else { - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2835_ic_set_irq: Bad irq %d\n", irq); - } - - bcm2835_ic_update(s); -} - -static const int irq_dups[] = { 7, 9, 10, 18, 19, 53, 54, 55, 56, 57, 62, -1 }; - -static uint64_t bcm2835_ic_read(void *opaque, hwaddr offset, - unsigned size) -{ - BCM2835IcState *s = (BCM2835IcState *)opaque; - int i; - int p = 0; - uint32_t res = 0; - - switch (offset) { - case 0x00: /* IRQ basic pending */ - /* bits 0-7 - ARM irqs */ - res = (s->level[IR_B] & s->irq_enable[IR_B]) & 0xff; - for (i = 0; i < 64; i++) { - if (i == irq_dups[p]) { - /* bits 10-20 - selected GPU irqs */ - if (s->level[i >> 5] & s->irq_enable[i >> 5] - & (1u << (i & 0x1f))) { - res |= (1u << (10 + p)); - } - p++; - } else { - /* bits 8-9 - one or more bits set in pending registers 1-2 */ - if (s->level[i >> 5] & s->irq_enable[i >> 5] - & (1u << (i & 0x1f))) { - res |= (1u << (8 + (i >> 5))); - } - } - } - break; - case 0x04: /* IRQ pending 1 */ - res = s->level[IR_1] & s->irq_enable[IR_1]; - break; - case 0x08: /* IRQ pending 2 */ - res = s->level[IR_2] & s->irq_enable[IR_2]; - break; - case 0x0C: /* FIQ register */ - res = (s->fiq_enable << 7) | s->fiq_select; - break; - case 0x10: /* Interrupt enable register 1 */ - res = s->irq_enable[IR_1]; - break; - case 0x14: /* Interrupt enable register 2 */ - res = s->irq_enable[IR_2]; - break; - case 0x18: /* Base interrupt enable register */ - res = s->irq_enable[IR_B]; - break; - case 0x1C: /* Interrupt disable register 1 */ - res = ~s->irq_enable[IR_1]; - break; - case 0x20: /* Interrupt disable register 2 */ - res = ~s->irq_enable[IR_2]; - break; - case 0x24: /* Base interrupt disable register */ - res = ~s->irq_enable[IR_B]; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2835_ic_read: Bad offset %x\n", (int)offset); - return 0; - } - - return res; -} - -static void bcm2835_ic_write(void *opaque, hwaddr offset, - uint64_t val, unsigned size) -{ - BCM2835IcState *s = (BCM2835IcState *)opaque; - - switch (offset) { - case 0x0C: /* FIQ register */ - s->fiq_select = (val & 0x7f); - s->fiq_enable = (val >> 7) & 0x1; - break; - case 0x10: /* Interrupt enable register 1 */ - s->irq_enable[IR_1] |= val; - break; - case 0x14: /* Interrupt enable register 2 */ - s->irq_enable[IR_2] |= val; - break; - case 0x18: /* Base interrupt enable register */ - s->irq_enable[IR_B] |= (val & 0xff); - break; - case 0x1C: /* Interrupt disable register 1 */ - s->irq_enable[IR_1] &= ~val; - break; - case 0x20: /* Interrupt disable register 2 */ - s->irq_enable[IR_2] &= ~val; - break; - case 0x24: /* Base interrupt disable register */ - s->irq_enable[IR_B] &= (~val & 0xff); - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2835_ic_write: Bad offset %x\n", (int)offset); - return; - } - bcm2835_ic_update(s); -} - -static const MemoryRegionOps bcm2835_ic_ops = { - .read = bcm2835_ic_read, - .write = bcm2835_ic_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void bcm2835_ic_reset(DeviceState *d) -{ - BCM2835IcState *s = BCM2835_IC(d); - int i; - - for (i = 0; i < 3; i++) { - s->irq_enable[i] = 0; - } - s->fiq_enable = 0; - s->fiq_select = 0; -} - -static void bcm2835_ic_init(Object *obj) -{ - BCM2835IcState *s = BCM2835_IC(obj); - - memory_region_init_io(&s->iomem, obj, &bcm2835_ic_ops, s, TYPE_BCM2835_IC, - 0x200); - sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); - - qdev_init_gpio_in(DEVICE(s), bcm2835_ic_set_irq, 72); - sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq); - sysbus_init_irq(SYS_BUS_DEVICE(s), &s->fiq); -} - -static void bcm2835_ic_realize(DeviceState *dev, Error **errp) -{ -} - -static const VMStateDescription vmstate_bcm2835_ic = { - .name = TYPE_BCM2835_IC, - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(level, BCM2835IcState, 3), - VMSTATE_UINT32_ARRAY(irq_enable, BCM2835IcState, 3), - VMSTATE_INT32(fiq_enable, BCM2835IcState), - VMSTATE_INT32(fiq_select, BCM2835IcState), - VMSTATE_END_OF_LIST() - } -}; - -static void bcm2835_ic_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = bcm2835_ic_realize; - dc->reset = bcm2835_ic_reset; - dc->vmsd = &vmstate_bcm2835_ic; -} - -static TypeInfo bcm2835_ic_info = { - .name = TYPE_BCM2835_IC, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(BCM2835IcState), - .class_init = bcm2835_ic_class_init, - .instance_init = bcm2835_ic_init, -}; - -static void bcm2835_ic_register_types(void) -{ - type_register_static(&bcm2835_ic_info); -} - -type_init(bcm2835_ic_register_types) +/* + * Raspberry Pi emulation (c) 2012 Gregory Estrade + * This code is licensed under the GNU GPLv2 and later. + * Heavily based on pl190.c, copyright terms below: + * + * Arm PrimeCell PL190 Vector Interrupt Controller + * + * Copyright (c) 2006 CodeSourcery. + * Written by Paul Brook + * + * This code is licensed under the GPL. + */ + +#include "hw/intc/bcm2835_ic.h" + +#define GPU_IRQS 64 +#define ARM_IRQS 8 + +#define IRQ_PENDING_BASIC 0x00 /* IRQ basic pending */ +#define IRQ_PENDING_1 0x04 /* IRQ pending 1 */ +#define IRQ_PENDING_2 0x08 /* IRQ pending 2 */ +#define FIQ_CONTROL 0x0C /* FIQ register */ +#define IRQ_ENABLE_1 0x10 /* Interrupt enable register 1 */ +#define IRQ_ENABLE_2 0x14 /* Interrupt enable register 2 */ +#define IRQ_ENABLE_BASIC 0x18 /* Base interrupt enable register */ +#define IRQ_DISABLE_1 0x1C /* Interrupt disable register 1 */ +#define IRQ_DISABLE_2 0x20 /* Interrupt disable register 2 */ +#define IRQ_DISABLE_BASIC 0x24 /* Base interrupt disable register */ + +/* Update interrupts. */ +static void bcm2835_ic_update(BCM2835ICState *s) +{ + bool set = false; + + if (s->fiq_enable) { + if (s->fiq_select >= GPU_IRQS) { + /* ARM IRQ */ + set = extract32(s->arm_irq_level, s->fiq_select - GPU_IRQS, 1); + } else { + set = extract64(s->gpu_irq_level, s->fiq_select, 1); + } + } + qemu_set_irq(s->fiq, set); + + set = (s->gpu_irq_level & s->gpu_irq_enable) + || (s->arm_irq_level & s->arm_irq_enable); + qemu_set_irq(s->irq, set); + +} + +static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level) +{ + BCM2835ICState *s = opaque; + assert(irq >= 0 && irq < 64); + s->gpu_irq_level = deposit64(s->gpu_irq_level, irq, 1, level != 0); + bcm2835_ic_update(s); +} + +static void bcm2835_ic_set_arm_irq(void *opaque, int irq, int level) +{ + BCM2835ICState *s = opaque; + assert(irq >= 0 && irq < 8); + s->arm_irq_level = deposit32(s->arm_irq_level, irq, 1, level != 0); + bcm2835_ic_update(s); +} + +static const int irq_dups[] = { 7, 9, 10, 18, 19, 53, 54, 55, 56, 57, 62 }; + +static uint64_t bcm2835_ic_read(void *opaque, hwaddr offset, unsigned size) +{ + BCM2835ICState *s = opaque; + uint32_t res = 0; + uint64_t gpu_pending = s->gpu_irq_level & s->gpu_irq_enable; + int i; + + switch (offset) { + case IRQ_PENDING_BASIC: + /* bits 0-7: ARM irqs */ + res = s->arm_irq_level & s->arm_irq_enable; + + /* bits 8 & 9: pending registers 1 & 2 */ + res |= (((uint32_t)gpu_pending) != 0) << 8; + res |= ((gpu_pending >> 32) != 0) << 9; + + /* bits 10-20: selected GPU IRQs */ + for (i = 0; i < ARRAY_SIZE(irq_dups); i++) { + res |= extract64(gpu_pending, irq_dups[i], 1) << (i + 10); + } + break; + case IRQ_PENDING_1: /* IRQ pending 1 */ + res = gpu_pending; + break; + case IRQ_PENDING_2: /* IRQ pending 2 */ + res = gpu_pending >> 32; + break; + case FIQ_CONTROL: /* FIQ register */ + res = (s->fiq_enable << 7) | s->fiq_select; + break; + case IRQ_ENABLE_1: /* Interrupt enable register 1 */ + res = s->gpu_irq_enable; + break; + case IRQ_ENABLE_2: /* Interrupt enable register 2 */ + res = s->gpu_irq_enable >> 32; + break; + case IRQ_ENABLE_BASIC: /* Base interrupt enable register */ + res = s->arm_irq_enable; + break; + case IRQ_DISABLE_1: /* Interrupt disable register 1 */ + res = ~s->gpu_irq_enable; + break; + case IRQ_DISABLE_2: /* Interrupt disable register 2 */ + res = ~s->gpu_irq_enable >> 32; + break; + case IRQ_DISABLE_BASIC: /* Base interrupt disable register */ + res = ~s->arm_irq_enable; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); + return 0; + } + + return res; +} + +static void bcm2835_ic_write(void *opaque, hwaddr offset, uint64_t val, + unsigned size) +{ + BCM2835ICState *s = opaque; + + switch (offset) { + case FIQ_CONTROL: + s->fiq_select = (val & 0x7f); + s->fiq_enable = (val >> 7) & 0x1; + break; + case IRQ_ENABLE_1: + s->gpu_irq_enable |= val; + break; + case IRQ_ENABLE_2: + s->gpu_irq_enable |= val << 32; + break; + case IRQ_ENABLE_BASIC: + s->arm_irq_enable |= val & 0xff; + break; + case IRQ_DISABLE_1: + s->gpu_irq_enable &= ~val; + break; + case IRQ_DISABLE_2: + s->gpu_irq_enable &= ~(val << 32); + break; + case IRQ_DISABLE_BASIC: + s->arm_irq_enable &= ~val & 0xff; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); + return; + } + bcm2835_ic_update(s); +} + +static const MemoryRegionOps bcm2835_ic_ops = { + .read = bcm2835_ic_read, + .write = bcm2835_ic_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid.min_access_size = 4, + .valid.max_access_size = 4, +}; + +static void bcm2835_ic_reset(DeviceState *d) +{ + BCM2835ICState *s = BCM2835_IC(d); + + s->gpu_irq_enable = 0; + s->arm_irq_enable = 0; + s->fiq_enable = false; + s->fiq_select = 0; +} + +static void bcm2835_ic_init(Object *obj) +{ + BCM2835ICState *s = BCM2835_IC(obj); + + memory_region_init_io(&s->iomem, obj, &bcm2835_ic_ops, s, TYPE_BCM2835_IC, + 0x200); + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); + + qdev_init_gpio_in_named(DEVICE(s), bcm2835_ic_set_gpu_irq, + BCM2835_IC_GPU_IRQ, GPU_IRQS); + qdev_init_gpio_in_named(DEVICE(s), bcm2835_ic_set_arm_irq, + BCM2835_IC_ARM_IRQ, ARM_IRQS); + + sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq); + sysbus_init_irq(SYS_BUS_DEVICE(s), &s->fiq); +} + +static const VMStateDescription vmstate_bcm2835_ic = { + .name = TYPE_BCM2835_IC, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT64(gpu_irq_level, BCM2835ICState), + VMSTATE_UINT64(gpu_irq_enable, BCM2835ICState), + VMSTATE_UINT8(arm_irq_level, BCM2835ICState), + VMSTATE_UINT8(arm_irq_enable, BCM2835ICState), + VMSTATE_BOOL(fiq_enable, BCM2835ICState), + VMSTATE_UINT8(fiq_select, BCM2835ICState), + VMSTATE_END_OF_LIST() + } +}; + +static void bcm2835_ic_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->reset = bcm2835_ic_reset; + dc->vmsd = &vmstate_bcm2835_ic; +} + +static TypeInfo bcm2835_ic_info = { + .name = TYPE_BCM2835_IC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BCM2835ICState), + .class_init = bcm2835_ic_class_init, + .instance_init = bcm2835_ic_init, +}; + +static void bcm2835_ic_register_types(void) +{ + type_register_static(&bcm2835_ic_info); +} + +type_init(bcm2835_ic_register_types) diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c old mode 100644 new mode 100755 index c47b36f34f..d68b4d9f7c --- a/hw/intc/bcm2836_control.c +++ b/hw/intc/bcm2836_control.c @@ -127,7 +127,7 @@ static void bcm2836_control_update(BCM2836ControlState *s) static void bcm2836_control_set_local_irq(void *opaque, int core, int local_irq, int level) { - BCM2836ControlState *s = (BCM2836ControlState *)opaque; + BCM2836ControlState *s = opaque; assert(core >= 0 && core < BCM2836_NCORES); assert(local_irq >= 0 && local_irq <= IRQ_CNTVIRQ); @@ -168,7 +168,7 @@ static void bcm2836_control_set_local_irq3(void *opaque, int core, int level) static void bcm2836_control_set_gpu_irq(void *opaque, int irq, int level) { - BCM2836ControlState *s = (BCM2836ControlState *)opaque; + BCM2836ControlState *s = opaque; s->gpu_irq = level; @@ -177,17 +177,16 @@ static void bcm2836_control_set_gpu_irq(void *opaque, int irq, int level) static void bcm2836_control_set_gpu_fiq(void *opaque, int irq, int level) { - BCM2836ControlState *s = (BCM2836ControlState *)opaque; + BCM2836ControlState *s = opaque; s->gpu_fiq = level; bcm2836_control_update(s); } -static uint64_t bcm2836_control_read(void *opaque, hwaddr offset, - unsigned size) +static uint64_t bcm2836_control_read(void *opaque, hwaddr offset, unsigned size) { - BCM2836ControlState *s = (BCM2836ControlState *)opaque; + BCM2836ControlState *s = opaque; if (offset == 0xc) { /* GPU interrupt routing */ @@ -210,16 +209,16 @@ static uint64_t bcm2836_control_read(void *opaque, hwaddr offset, /* Mailboxes */ return s->mailboxes[(offset - 0xc0) >> 2]; } else { - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2836_control_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); return 0; } } static void bcm2836_control_write(void *opaque, hwaddr offset, - uint64_t val, unsigned size) + uint64_t val, unsigned size) { - BCM2836ControlState *s = (BCM2836ControlState *)opaque; + BCM2836ControlState *s = opaque; if (offset == 0xc) { /* GPU interrupt routing */ @@ -238,8 +237,8 @@ static void bcm2836_control_write(void *opaque, hwaddr offset, /* Mailbox clear registers */ s->mailboxes[(offset - 0xc0) >> 2] &= ~val; } else { - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2836_control_write: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); return; } @@ -299,10 +298,6 @@ static void bcm2836_control_init(Object *obj) qdev_init_gpio_out_named(dev, s->fiq, "fiq", BCM2836_NCORES); } -static void bcm2836_control_realize(DeviceState *dev, Error **errp) -{ -} - static const VMStateDescription vmstate_bcm2836_control = { .name = TYPE_BCM2836_CONTROL, .version_id = 1, @@ -323,7 +318,6 @@ static void bcm2836_control_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->realize = bcm2836_control_realize; dc->reset = bcm2836_control_reset; dc->vmsd = &vmstate_bcm2836_control; } diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs old mode 100644 new mode 100755 index bb896d31ee..5ea1f82f49 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -34,10 +34,10 @@ obj-$(CONFIG_OMAP) += omap_gpmc.o obj-$(CONFIG_OMAP) += omap_l4.o obj-$(CONFIG_OMAP) += omap_sdrc.o obj-$(CONFIG_OMAP) += omap_tap.o +obj-$(CONFIG_RASPI) += bcm2835_mbox.o obj-$(CONFIG_RASPI) += bcm2835_mphi.o obj-$(CONFIG_RASPI) += bcm2835_power.o obj-$(CONFIG_RASPI) += bcm2835_property.o -obj-$(CONFIG_RASPI) += bcm2835_sbm.o obj-$(CONFIG_RASPI) += bcm2835_vchiq.o obj-$(CONFIG_SLAVIO) += slavio_misc.o obj-$(CONFIG_ZYNQ) += zynq_slcr.o diff --git a/hw/misc/bcm2835_mbox.c b/hw/misc/bcm2835_mbox.c new file mode 100644 index 0000000000..69b8e2a159 --- /dev/null +++ b/hw/misc/bcm2835_mbox.c @@ -0,0 +1,323 @@ +/* + * Raspberry Pi emulation (c) 2012 Gregory Estrade + * This code is licensed under the GNU GPLv2 and later. + * + * This file models the system mailboxes, which are used for + * communication with low-bandwidth GPU peripherals. Refs: + * https://github.com/raspberrypi/firmware/wiki/Mailboxes + * https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes + */ + +#include "hw/misc/bcm2835_mbox.h" + +/* Mailbox status register (...0x98) */ +#define ARM_MS_FULL 0x80000000 +#define ARM_MS_EMPTY 0x40000000 +#define ARM_MS_LEVEL 0x400000FF /* Max. value depends on mailbox depth */ + +/* MAILBOX config/status register (...0x9C) */ +/* ANY write to this register clears the error bits! */ +#define ARM_MC_IHAVEDATAIRQEN 0x00000001 /* mbox irq enable: has data */ +#define ARM_MC_IHAVESPACEIRQEN 0x00000002 /* mbox irq enable: has space */ +#define ARM_MC_OPPISEMPTYIRQEN 0x00000004 /* mbox irq enable: Opp is empty */ +#define ARM_MC_MAIL_CLEAR 0x00000008 /* mbox clear write 1, then 0 */ +#define ARM_MC_IHAVEDATAIRQPEND 0x00000010 /* mbox irq pending: has space */ +#define ARM_MC_IHAVESPACEIRQPEND 0x00000020 /* mbox irq pending: Opp is empty */ +#define ARM_MC_OPPISEMPTYIRQPEND 0x00000040 /* mbox irq pending */ +/* Bit 7 is unused */ +#define ARM_MC_ERRNOOWN 0x00000100 /* error : none owner read from mailbox */ +#define ARM_MC_ERROVERFLW 0x00000200 /* error : write to fill mailbox */ +#define ARM_MC_ERRUNDRFLW 0x00000400 /* error : read from empty mailbox */ + +static void mbox_update_status(BCM2835Mbox *mb) +{ + mb->status &= ~(ARM_MS_EMPTY | ARM_MS_FULL); + if (mb->count == 0) { + mb->status |= ARM_MS_EMPTY; + } else if (mb->count == MBOX_SIZE) { + mb->status |= ARM_MS_FULL; + } +} + +static void mbox_init(BCM2835Mbox *mb) +{ + int n; + + mb->count = 0; + mb->config = 0; + for (n = 0; n < MBOX_SIZE; n++) { + mb->reg[n] = MBOX_INVALID_DATA; + } + mbox_update_status(mb); +} + +static uint32_t mbox_pull(BCM2835Mbox *mb, int index) +{ + int n; + uint32_t val; + + assert(mb->count > 0); + assert(index < mb->count); + + val = mb->reg[index]; + for (n = index + 1; n < mb->count; n++) { + mb->reg[n - 1] = mb->reg[n]; + } + mb->count--; + mb->reg[mb->count] = MBOX_INVALID_DATA; + + mbox_update_status(mb); + + return val; +} + +static void mbox_push(BCM2835Mbox *mb, uint32_t val) +{ + assert(mb->count < MBOX_SIZE); + mb->reg[mb->count++] = val; + mbox_update_status(mb); +} + +static void bcm2835_mbox_update(BCM2835MboxState *s) +{ + uint32_t value; + bool set; + int n; + + /* Avoid unwanted recursive calls */ + s->mbox_irq_disabled = true; + + /* Get pending responses and put them in the vc->arm mbox, + * as long as it's not full */ + for (n = 0; n < MBOX_CHAN_COUNT; n++) { + while (s->available[n] && !(s->mbox[0].status & ARM_MS_FULL)) { + value = ldl_phys(&s->mbox_as, n << MBOX_AS_CHAN_SHIFT); + if (value == MBOX_INVALID_DATA) { + /* Interrupt pending, but there's no data. Hmmm... */ + hw_error("%s: spurious interrupt on channel %d", __func__, n); + } + mbox_push(&s->mbox[0], value); + } + } + + /* Try to push pending requests from the arm->vc mbox */ + /* TODO (?) */ + + /* Re-enable calls from the IRQ routine */ + s->mbox_irq_disabled = false; + + /* Update ARM IRQ status */ + set = false; + s->mbox[0].config &= ~ARM_MC_IHAVEDATAIRQPEND; + if (!(s->mbox[0].status & ARM_MS_EMPTY)) { + s->mbox[0].config |= ARM_MC_IHAVEDATAIRQPEND; + if (s->mbox[0].config & ARM_MC_IHAVEDATAIRQEN) { + set = true; + } + } + qemu_set_irq(s->arm_irq, set); +} + +static void bcm2835_mbox_set_irq(void *opaque, int irq, int level) +{ + BCM2835MboxState *s = opaque; + + s->available[irq] = level; + + /* avoid recursively calling bcm2835_mbox_update when the interrupt + * status changes due to the ldl_phys call within that function */ + if (!s->mbox_irq_disabled) { + bcm2835_mbox_update(s); + } +} + +static uint64_t bcm2835_mbox_read(void *opaque, hwaddr offset, unsigned size) +{ + BCM2835MboxState *s = opaque; + uint32_t res = 0; + + offset &= 0xff; + + switch (offset) { + case 0x80 ... 0x8c: /* MAIL0_READ */ + if (s->mbox[0].status & ARM_MS_EMPTY) { + res = MBOX_INVALID_DATA; + } else { + res = mbox_pull(&s->mbox[0], 0); + } + break; + case 0x90: /* MAIL0_PEEK */ + res = s->mbox[0].reg[0]; + break; + case 0x94: /* MAIL0_SENDER */ + break; + case 0x98: /* MAIL0_STATUS */ + res = s->mbox[0].status; + break; + case 0x9c: /* MAIL0_CONFIG */ + res = s->mbox[0].config; + break; + case 0xb8: /* MAIL1_STATUS */ + res = s->mbox[1].status; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); + return 0; + } + + bcm2835_mbox_update(s); + + return res; +} + +static void bcm2835_mbox_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + BCM2835MboxState *s = opaque; + hwaddr childaddr; + uint8_t ch; + + offset &= 0xff; + + switch (offset) { + case 0x94: /* MAIL0_SENDER */ + break; + + case 0x9c: /* MAIL0_CONFIG */ + s->mbox[0].config &= ~ARM_MC_IHAVEDATAIRQEN; + s->mbox[0].config |= value & ARM_MC_IHAVEDATAIRQEN; + break; + + case 0xa0 ... 0xac: + if (s->mbox[1].status & ARM_MS_FULL) { + /* Mailbox full */ + qemu_log_mask(LOG_GUEST_ERROR, "%s: mailbox full\n", __func__); + } else { + ch = value & 0xf; + if (ch < MBOX_CHAN_COUNT) { + childaddr = ch << MBOX_AS_CHAN_SHIFT; + if (ldl_phys(&s->mbox_as, childaddr + MBOX_AS_PENDING)) { + /* Child busy, push delayed. Push it in the arm->vc mbox */ + mbox_push(&s->mbox[1], value); + } else { + /* Push it directly to the child device */ + stl_phys(&s->mbox_as, childaddr, value); + } + } else { + /* Invalid channel number */ + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid channel %u\n", + __func__, ch); + } + } + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); + return; + } + + bcm2835_mbox_update(s); +} + +static const MemoryRegionOps bcm2835_mbox_ops = { + .read = bcm2835_mbox_read, + .write = bcm2835_mbox_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid.min_access_size = 4, + .valid.max_access_size = 4, +}; + +/* vmstate of a single mailbox */ +static const VMStateDescription vmstate_bcm2835_mbox_box = { + .name = TYPE_BCM2835_MBOX "_box", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(reg, BCM2835Mbox, MBOX_SIZE), + VMSTATE_UINT32(count, BCM2835Mbox), + VMSTATE_UINT32(status, BCM2835Mbox), + VMSTATE_UINT32(config, BCM2835Mbox), + VMSTATE_END_OF_LIST() + } +}; + +/* vmstate of the entire device */ +static const VMStateDescription vmstate_bcm2835_mbox = { + .name = TYPE_BCM2835_MBOX, + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_BOOL_ARRAY(available, BCM2835MboxState, MBOX_CHAN_COUNT), + VMSTATE_STRUCT_ARRAY(mbox, BCM2835MboxState, 2, 1, + vmstate_bcm2835_mbox_box, BCM2835Mbox), + VMSTATE_END_OF_LIST() + } +}; + +static void bcm2835_mbox_init(Object *obj) +{ + BCM2835MboxState *s = BCM2835_MBOX(obj); + memory_region_init_io(&s->iomem, obj, &bcm2835_mbox_ops, s, + TYPE_BCM2835_MBOX, 0x400); + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); + sysbus_init_irq(SYS_BUS_DEVICE(s), &s->arm_irq); + qdev_init_gpio_in(DEVICE(s), bcm2835_mbox_set_irq, MBOX_CHAN_COUNT); +} + +static void bcm2835_mbox_reset(DeviceState *dev) +{ + BCM2835MboxState *s = BCM2835_MBOX(dev); + int n; + + mbox_init(&s->mbox[0]); + mbox_init(&s->mbox[1]); + s->mbox_irq_disabled = false; + for (n = 0; n < MBOX_CHAN_COUNT; n++) { + s->available[n] = false; + } +} + +static void bcm2835_mbox_realize(DeviceState *dev, Error **errp) +{ + BCM2835MboxState *s = BCM2835_MBOX(dev); + Object *obj; + Error *err = NULL; + + obj = object_property_get_link(OBJECT(dev), "mbox_mr", &err); + if (obj == NULL) { + error_setg(errp, "%s: required mbox_mr link not found: %s", + __func__, error_get_pretty(err)); + return; + } + + s->mbox_mr = MEMORY_REGION(obj); + address_space_init(&s->mbox_as, s->mbox_mr, NULL); + bcm2835_mbox_reset(dev); +} + +static void bcm2835_mbox_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = bcm2835_mbox_realize; + dc->reset = bcm2835_mbox_reset; + dc->vmsd = &vmstate_bcm2835_mbox; +} + +static TypeInfo bcm2835_mbox_info = { + .name = TYPE_BCM2835_MBOX, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(BCM2835MboxState), + .class_init = bcm2835_mbox_class_init, + .instance_init = bcm2835_mbox_init, +}; + +static void bcm2835_mbox_register_types(void) +{ + type_register_static(&bcm2835_mbox_info); +} + +type_init(bcm2835_mbox_register_types) diff --git a/hw/misc/bcm2835_power.c b/hw/misc/bcm2835_power.c index 7db755b606..2485d8deff 100644 --- a/hw/misc/bcm2835_power.c +++ b/hw/misc/bcm2835_power.c @@ -3,8 +3,8 @@ * This code is licensed under the GNU GPLv2 and later. */ -#include "hw/arm/bcm2835_mbox.h" #include "hw/misc/bcm2835_power.h" +#include "hw/misc/bcm2835_mbox_defs.h" static uint64_t bcm2835_power_read(void *opaque, hwaddr offset, unsigned size) { diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c old mode 100644 new mode 100755 index 8bf3a07f34..e924781218 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -4,7 +4,7 @@ */ #include "hw/misc/bcm2835_property.h" -#include "hw/arm/bcm2835_mbox.h" +#include "hw/misc/bcm2835_mbox_defs.h" /* https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */ @@ -254,7 +254,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) default: qemu_log_mask(LOG_GUEST_ERROR, - "bcm2835_property: unhandled tag %08x\n", tag); + "bcm2835_property: unhandled tag %08x\n", tag); break; } @@ -277,62 +277,69 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) } static uint64_t bcm2835_property_read(void *opaque, hwaddr offset, - unsigned size) + unsigned size) { - BCM2835PropertyState *s = (BCM2835PropertyState *)opaque; + BCM2835PropertyState *s = opaque; uint32_t res = 0; switch (offset) { - case 0: + case MBOX_AS_DATA: res = MBOX_CHAN_PROPERTY | s->addr; - s->pending = 0; + s->pending = false; qemu_set_irq(s->mbox_irq, 0); break; - case 4: + + case MBOX_AS_PENDING: res = s->pending; break; + default: - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2835_property_read: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); return 0; } + return res; } static void bcm2835_property_write(void *opaque, hwaddr offset, - uint64_t value, unsigned size) + uint64_t value, unsigned size) { - BCM2835PropertyState *s = (BCM2835PropertyState *)opaque; + BCM2835PropertyState *s = opaque; + switch (offset) { - case 0: + case MBOX_AS_DATA: if (!s->pending) { - s->pending = 1; + s->pending = true; bcm2835_property_mbox_push(s, value); qemu_set_irq(s->mbox_irq, 1); } break; + default: - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2835_property_write: Bad offset %x\n", (int)offset); + qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", + __func__, offset); return; } } - static const MemoryRegionOps bcm2835_property_ops = { .read = bcm2835_property_read, .write = bcm2835_property_write, .endianness = DEVICE_NATIVE_ENDIAN, + .valid.min_access_size = 4, + .valid.max_access_size = 4, }; - static const VMStateDescription vmstate_bcm2835_property = { .name = TYPE_BCM2835_PROPERTY, .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField[]) { + VMSTATE_UINT32(addr, BCM2835PropertyState), + VMSTATE_BOOL(pending, BCM2835PropertyState), VMSTATE_END_OF_LIST() } }; @@ -341,11 +348,18 @@ static void bcm2835_property_init(Object *obj) { BCM2835PropertyState *s = BCM2835_PROPERTY(obj); memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_property_ops, s, - TYPE_BCM2835_PROPERTY, 0x10); + TYPE_BCM2835_PROPERTY, 0x10); sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); sysbus_init_irq(SYS_BUS_DEVICE(s), &s->mbox_irq); } +static void bcm2835_property_reset(DeviceState *dev) +{ + BCM2835PropertyState *s = BCM2835_PROPERTY(dev); + + s->pending = false; +} + static void bcm2835_property_realize(DeviceState *dev, Error **errp) { BCM2835PropertyState *s = BCM2835_PROPERTY(dev); @@ -353,23 +367,25 @@ static void bcm2835_property_realize(DeviceState *dev, Error **errp) Error *err = NULL; obj = object_property_get_link(OBJECT(dev), "bcm2835_fb", &err); - if (err || obj == NULL) { - error_setg(errp, "bcm2835_property: required bcm2835_fb link missing"); + if (obj == NULL) { + error_setg(errp, "%s: required bcm2835_fb link not found: %s", + __func__, error_get_pretty(err)); return; } s->fbdev = BCM2835_FB(obj); obj = object_property_get_link(OBJECT(dev), "dma_mr", &err); - if (err || obj == NULL) { - error_setg(errp, "bcm2835_property: required dma_mr link not found"); + if (obj == NULL) { + error_setg(errp, "%s: required dma_mr link not found: %s", + __func__, error_get_pretty(err)); return; } s->dma_mr = MEMORY_REGION(obj); address_space_init(&s->dma_as, s->dma_mr, NULL); - s->pending = 0; + bcm2835_property_reset(dev); } static void bcm2835_property_class_init(ObjectClass *klass, void *data) diff --git a/hw/misc/bcm2835_sbm.c b/hw/misc/bcm2835_sbm.c deleted file mode 100644 index a5c9324ff8..0000000000 --- a/hw/misc/bcm2835_sbm.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Raspberry Pi emulation (c) 2012 Gregory Estrade - * This code is licensed under the GNU GPLv2 and later. - */ - -#include "hw/misc/bcm2835_sbm.h" -#include "hw/arm/bcm2835_arm_control.h" - -static void mbox_update_status(BCM2835Mbox *mb) -{ - if (mb->count == 0) { - mb->status |= ARM_MS_EMPTY; - } else { - mb->status &= ~ARM_MS_EMPTY; - } - if (mb->count == MBOX_SIZE) { - mb->status |= ARM_MS_FULL; - } else { - mb->status &= ~ARM_MS_FULL; - } -} - -static void mbox_init(BCM2835Mbox *mb) -{ - int n; - mb->count = 0; - mb->config = 0; - for (n = 0; n < MBOX_SIZE; n++) { - mb->reg[n] = MBOX_INVALID_DATA; - } - mbox_update_status(mb); -} - -static uint32_t mbox_pull(BCM2835Mbox *mb, int index) -{ - int n; - uint32_t val; - - assert(mb->count > 0); - assert(index < mb->count); - - val = mb->reg[index]; - for (n = index + 1; n < mb->count; n++) { - mb->reg[n - 1] = mb->reg[n]; - } - mb->count--; - mb->reg[mb->count] = MBOX_INVALID_DATA; - - mbox_update_status(mb); - - return val; -} - -static void mbox_push(BCM2835Mbox *mb, uint32_t val) -{ - assert(mb->count < MBOX_SIZE); - mb->reg[mb->count++] = val; - mbox_update_status(mb); -} - -static void bcm2835_sbm_update(BCM2835SbmState *s) -{ - int set; - int done, n; - uint32_t value; - - /* Avoid unwanted recursive calls */ - s->mbox_irq_disabled = 1; - - /* Get pending responses and put them in the vc->arm mbox */ - done = 0; - while (!done) { - done = 1; - if (s->mbox[0].status & ARM_MS_FULL) { - /* vc->arm mbox full, exit */ - } else { - for (n = 0; n < MBOX_CHAN_COUNT; n++) { - if (s->available[n]) { - value = ldl_phys(&s->mbox_as, n<<4); - if (value != MBOX_INVALID_DATA) { - mbox_push(&s->mbox[0], value); - } else { - /* Hmmm... */ - } - done = 0; - break; - } - } - } - } - - /* Try to push pending requests from the arm->vc mbox */ - /* TODO (?) */ - - /* Re-enable calls from the IRQ routine */ - s->mbox_irq_disabled = 0; - - /* Update ARM IRQ status */ - set = 0; - if (s->mbox[0].status & ARM_MS_EMPTY) { - s->mbox[0].config &= ~ARM_MC_IHAVEDATAIRQPEND; - } else { - s->mbox[0].config |= ARM_MC_IHAVEDATAIRQPEND; - if (s->mbox[0].config & ARM_MC_IHAVEDATAIRQEN) { - set = 1; - } - } - qemu_set_irq(s->arm_irq, set); -} - -static void bcm2835_sbm_set_irq(void *opaque, int irq, int level) -{ - BCM2835SbmState *s = (BCM2835SbmState *)opaque; - s->available[irq] = level; - if (!s->mbox_irq_disabled) { - bcm2835_sbm_update(s); - } -} - -static uint64_t bcm2835_sbm_read(void *opaque, hwaddr offset, - unsigned size) -{ - BCM2835SbmState *s = (BCM2835SbmState *)opaque; - uint32_t res = 0; - - offset &= 0xff; - - switch (offset) { - case 0x80: /* MAIL0_READ */ - case 0x84: - case 0x88: - case 0x8c: - if (s->mbox[0].status & ARM_MS_EMPTY) { - res = MBOX_INVALID_DATA; - } else { - res = mbox_pull(&s->mbox[0], 0); - } - break; - case 0x90: /* MAIL0_PEEK */ - res = s->mbox[0].reg[0]; - break; - case 0x94: /* MAIL0_SENDER */ - break; - case 0x98: /* MAIL0_STATUS */ - res = s->mbox[0].status; - break; - case 0x9c: /* MAIL0_CONFIG */ - res = s->mbox[0].config; - break; - case 0xb8: /* MAIL1_STATUS */ - res = s->mbox[1].status; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2835_sbm_read: Bad offset %x\n", (int)offset); - return 0; - } - - bcm2835_sbm_update(s); - - return res; -} - -static void bcm2835_sbm_write(void *opaque, hwaddr offset, - uint64_t value, unsigned size) -{ - int ch; - - BCM2835SbmState *s = (BCM2835SbmState *)opaque; - - offset &= 0xff; - - switch (offset) { - case 0x94: /* MAIL0_SENDER */ - break; - case 0x9c: /* MAIL0_CONFIG */ - s->mbox[0].config &= ~ARM_MC_IHAVEDATAIRQEN; - s->mbox[0].config |= value & ARM_MC_IHAVEDATAIRQEN; - break; - case 0xa0: - case 0xa4: - case 0xa8: - case 0xac: - if (s->mbox[1].status & ARM_MS_FULL) { - /* Guest error */ - } else { - ch = value & 0xf; - if (ch < MBOX_CHAN_COUNT) { - if (ldl_phys(&s->mbox_as, (ch<<4) + 4)) { - /* Push delayed, push it in the arm->vc mbox */ - mbox_push(&s->mbox[1], value); - } else { - stl_phys(&s->mbox_as, ch<<4, value); - } - } else { - /* Invalid channel number */ - } - } - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "bcm2835_sbm_write: Bad offset %x\n", (int)offset); - return; - } - - bcm2835_sbm_update(s); -} - -static const MemoryRegionOps bcm2835_sbm_ops = { - .read = bcm2835_sbm_read, - .write = bcm2835_sbm_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static const VMStateDescription vmstate_bcm2835_sbm = { - .name = TYPE_BCM2835_SBM, - .version_id = 1, - .minimum_version_id = 1, - .minimum_version_id_old = 1, - .fields = (VMStateField[]) { - VMSTATE_END_OF_LIST() - } -}; - -static void bcm2835_sbm_init(Object *obj) -{ - BCM2835SbmState *s = BCM2835_SBM(obj); - memory_region_init_io(&s->iomem, obj, &bcm2835_sbm_ops, s, - TYPE_BCM2835_SBM, 0x400); - sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); - sysbus_init_irq(SYS_BUS_DEVICE(s), &s->arm_irq); - qdev_init_gpio_in(DEVICE(s), bcm2835_sbm_set_irq, MBOX_CHAN_COUNT); -} - -static void bcm2835_sbm_realize(DeviceState *dev, Error **errp) -{ - int n; - BCM2835SbmState *s = BCM2835_SBM(dev); - Object *obj; - Error *err = NULL; - - obj = object_property_get_link(OBJECT(dev), "mbox_mr", &err); - if (err || obj == NULL) { - error_setg(errp, "bcm2835_sbm: required mbox_mr link not found"); - return; - } - - s->mbox_mr = MEMORY_REGION(obj); - address_space_init(&s->mbox_as, s->mbox_mr, NULL); - - mbox_init(&s->mbox[0]); - mbox_init(&s->mbox[1]); - s->mbox_irq_disabled = 0; - for (n = 0; n < MBOX_CHAN_COUNT; n++) { - s->available[n] = 0; - } -} - -static void bcm2835_sbm_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = bcm2835_sbm_realize; - dc->vmsd = &vmstate_bcm2835_sbm; -} - -static TypeInfo bcm2835_sbm_info = { - .name = TYPE_BCM2835_SBM, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(BCM2835SbmState), - .class_init = bcm2835_sbm_class_init, - .instance_init = bcm2835_sbm_init, -}; - -static void bcm2835_sbm_register_types(void) -{ - type_register_static(&bcm2835_sbm_info); -} - -type_init(bcm2835_sbm_register_types) diff --git a/hw/misc/bcm2835_vchiq.c b/hw/misc/bcm2835_vchiq.c index 185d7812fd..21c109cc81 100644 --- a/hw/misc/bcm2835_vchiq.c +++ b/hw/misc/bcm2835_vchiq.c @@ -4,7 +4,7 @@ */ #include "hw/misc/bcm2835_vchiq.h" -#include "hw/arm/bcm2835_mbox.h" +#include "hw/misc/bcm2835_mbox_defs.h" static uint64_t bcm2835_vchiq_read(void *opaque, hwaddr offset, unsigned size) diff --git a/include/hw/arm/bcm2835_arm_control.h b/include/hw/arm/bcm2835_arm_control.h deleted file mode 100644 index 28acba8514..0000000000 --- a/include/hw/arm/bcm2835_arm_control.h +++ /dev/null @@ -1,481 +0,0 @@ -/* - * linux/arch/arm/mach-bcm2708/arm_control.h - * - * Copyright (C) 2010 Broadcom - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef BCM2708_ARM_CONTROL_H_ -#define BCM2708_ARM_CONTROL_H_ - -/* - * Definitions and addresses for the ARM CONTROL logic - * This file is manually generated. - */ - -#define ARM_BASE 0x7E00B000 - -/* Basic configuration */ -#define ARM_CONTROL0 HW_REGISTER_RW(ARM_BASE+0x000) -#define ARM_C0_SIZ128M 0x00000000 -#define ARM_C0_SIZ256M 0x00000001 -#define ARM_C0_SIZ512M 0x00000002 -#define ARM_C0_SIZ1G 0x00000003 -#define ARM_C0_BRESP0 0x00000000 -#define ARM_C0_BRESP1 0x00000004 -#define ARM_C0_BRESP2 0x00000008 -#define ARM_C0_BOOTHI 0x00000010 -#define ARM_C0_UNUSED05 0x00000020 /* free */ -#define ARM_C0_FULLPERI 0x00000040 -#define ARM_C0_UNUSED78 0x00000180 /* free */ -#define ARM_C0_JTAGMASK 0x00000E00 -#define ARM_C0_JTAGOFF 0x00000000 -#define ARM_C0_JTAGBASH 0x00000800 /* Debug on GPIO off */ -#define ARM_C0_JTAGGPIO 0x00000C00 /* Debug on GPIO on */ -#define ARM_C0_APROTMSK 0x0000F000 -#define ARM_C0_DBG0SYNC 0x00010000 /* VPU0 halt sync */ -#define ARM_C0_DBG1SYNC 0x00020000 /* VPU1 halt sync */ -#define ARM_C0_SWDBGREQ 0x00040000 /* HW debug request */ -#define ARM_C0_PASSHALT 0x00080000 /* ARM halt passed to debugger */ -#define ARM_C0_PRIO_PER 0x00F00000 /* per priority mask */ -#define ARM_C0_PRIO_L2 0x0F000000 -#define ARM_C0_PRIO_UC 0xF0000000 - -#define ARM_C0_APROTPASS 0x0000A000 /* Translate 1:1 */ -#define ARM_C0_APROTUSER 0x00000000 /* Only user mode */ -#define ARM_C0_APROTSYST 0x0000F000 /* Only system mode */ - - -#define ARM_CONTROL1 HW_REGISTER_RW(ARM_BASE+0x440) -#define ARM_C1_TIMER 0x00000001 /* re-route timer IRQ to VC */ -#define ARM_C1_MAIL 0x00000002 /* re-route Mail IRQ to VC */ -#define ARM_C1_BELL0 0x00000004 /* re-route Doorbell 0 to VC */ -#define ARM_C1_BELL1 0x00000008 /* re-route Doorbell 1 to VC */ -#define ARM_C1_PERSON 0x00000100 /* peripherals on */ -#define ARM_C1_REQSTOP 0x00000200 /* ASYNC bridge request stop */ - -#define ARM_STATUS HW_REGISTER_RW(ARM_BASE+0x444) -#define ARM_S_ACKSTOP 0x80000000 /* Bridge stopped */ -#define ARM_S_READPEND 0x000003FF /* pending reads counter */ -#define ARM_S_WRITPEND 0x000FFC00 /* pending writes counter */ - -#define ARM_ERRHALT HW_REGISTER_RW(ARM_BASE+0x448) -#define ARM_EH_PERIBURST 0x00000001 /* Burst write seen on peri bus */ -#define ARM_EH_ILLADDRS1 0x00000002 /* Address bits 25-27 error */ -#define ARM_EH_ILLADDRS2 0x00000004 /* Address bits 31-28 error */ -#define ARM_EH_VPU0HALT 0x00000008 /* VPU0 halted & in debug mode */ -#define ARM_EH_VPU1HALT 0x00000010 /* VPU1 halted & in debug mode */ -#define ARM_EH_ARMHALT 0x00000020 /* ARM in halted debug mode */ - -#define ARM_ID_SECURE HW_REGISTER_RW(ARM_BASE+0x00C) -#define ARM_ID HW_REGISTER_RW(ARM_BASE+0x44C) -#define ARM_IDVAL 0x364D5241 - -/* Translation memory */ -#define ARM_TRANSLATE HW_REGISTER_RW(ARM_BASE+0x100) -/* 32 locations: 0x100.. 0x17F */ -/* 32 spare means we CAN go to 64 pages.... */ - - -/* Interrupts */ -#define ARM_IRQ_PEND0 HW_REGISTER_RW(ARM_BASE+0x200) /* Top IRQ bits */ -#define ARM_I0_TIMER 0x00000001 /* timer IRQ */ -#define ARM_I0_MAIL 0x00000002 /* Mail IRQ */ -#define ARM_I0_BELL0 0x00000004 /* Doorbell 0 */ -#define ARM_I0_BELL1 0x00000008 /* Doorbell 1 */ -#define ARM_I0_BANK1 0x00000100 /* Bank1 IRQ */ -#define ARM_I0_BANK2 0x00000200 /* Bank2 IRQ */ - -#define ARM_IRQ_PEND1 HW_REGISTER_RW(ARM_BASE+0x204) /* All bank1 IRQ bits */ -/* todo: all I1_interrupt sources */ -#define ARM_IRQ_PEND2 HW_REGISTER_RW(ARM_BASE+0x208) /* All bank2 IRQ bits */ -/* todo: all I2_interrupt sources */ - -#define ARM_IRQ_FAST HW_REGISTER_RW(ARM_BASE+0x20C) /* FIQ control */ -#define ARM_IF_INDEX 0x0000007F /* FIQ select */ -#define ARM_IF_ENABLE 0x00000080 /* FIQ enable */ -#define ARM_IF_VCMASK 0x0000003F /* FIQ = (index from VC source) */ -#define ARM_IF_TIMER 0x00000040 /* FIQ = ARM timer */ -#define ARM_IF_MAIL 0x00000041 /* FIQ = ARM Mail */ -#define ARM_IF_BELL0 0x00000042 /* FIQ = ARM Doorbell 0 */ -#define ARM_IF_BELL1 0x00000043 /* FIQ = ARM Doorbell 1 */ -#define ARM_IF_VP0HALT 0x00000044 /* FIQ = VPU0 Halt seen */ -#define ARM_IF_VP1HALT 0x00000045 /* FIQ = VPU1 Halt seen */ -#define ARM_IF_ILLEGAL 0x00000046 /* FIQ = Illegal access seen */ - -#define ARM_IRQ_ENBL1 HW_REGISTER_RW(ARM_BASE+0x210) /* Bank1 enable bits */ -#define ARM_IRQ_ENBL2 HW_REGISTER_RW(ARM_BASE+0x214) /* Bank2 enable bits */ -#define ARM_IRQ_ENBL3 HW_REGISTER_RW(ARM_BASE+0x218) /* ARM irqs enable bits */ -#define ARM_IRQ_DIBL1 HW_REGISTER_RW(ARM_BASE+0x21C) /* Bank1 disable bits */ -#define ARM_IRQ_DIBL2 HW_REGISTER_RW(ARM_BASE+0x220) /* Bank2 disable bits */ -#define ARM_IRQ_DIBL3 HW_REGISTER_RW(ARM_BASE+0x224) /* ARM irqs disable bits */ -#define ARM_IE_TIMER 0x00000001 /* Timer IRQ */ -#define ARM_IE_MAIL 0x00000002 /* Mail IRQ */ -#define ARM_IE_BELL0 0x00000004 /* Doorbell 0 */ -#define ARM_IE_BELL1 0x00000008 /* Doorbell 1 */ -#define ARM_IE_VP0HALT 0x00000010 /* VPU0 Halt */ -#define ARM_IE_VP1HALT 0x00000020 /* VPU1 Halt */ -#define ARM_IE_ILLEGAL 0x00000040 /* Illegal access seen */ - -/* Timer */ -/* For reg. fields see sp804 spec. */ -#define ARM_T_LOAD HW_REGISTER_RW(ARM_BASE+0x400) -#define ARM_T_VALUE HW_REGISTER_RW(ARM_BASE+0x404) -#define ARM_T_CONTROL HW_REGISTER_RW(ARM_BASE+0x408) -#define ARM_T_IRQCNTL HW_REGISTER_RW(ARM_BASE+0x40C) -#define ARM_T_RAWIRQ HW_REGISTER_RW(ARM_BASE+0x410) -#define ARM_T_MSKIRQ HW_REGISTER_RW(ARM_BASE+0x414) -#define ARM_T_RELOAD HW_REGISTER_RW(ARM_BASE+0x418) -#define ARM_T_PREDIV HW_REGISTER_RW(ARM_BASE+0x41c) -#define ARM_T_FREECNT HW_REGISTER_RW(ARM_BASE+0x420) - -#define TIMER_CTRL_ONESHOT (1 << 0) -#define TIMER_CTRL_32BIT (1 << 1) -#define TIMER_CTRL_DIV1 (0 << 2) -#define TIMER_CTRL_DIV16 (1 << 2) -#define TIMER_CTRL_DIV256 (2 << 2) -#define TIMER_CTRL_IE (1 << 5) -#define TIMER_CTRL_PERIODIC (1 << 6) -#define TIMER_CTRL_ENABLE (1 << 7) -#define TIMER_CTRL_DBGHALT (1 << 8) -#define TIMER_CTRL_ENAFREE (1 << 9) -#define TIMER_CTRL_FREEDIV_SHIFT 16) -#define TIMER_CTRL_FREEDIV_MASK 0xff - -/* Semaphores, Doorbells, Mailboxes */ -#define ARM_SBM_OWN0 (ARM_BASE+0x800) -#define ARM_SBM_OWN1 (ARM_BASE+0x900) -#define ARM_SBM_OWN2 (ARM_BASE+0xA00) -#define ARM_SBM_OWN3 (ARM_BASE+0xB00) - -/* MAILBOXES - * Register flags are common across all - * owner registers. See end of this section - * - * Semaphores, Doorbells, Mailboxes Owner 0 - * - */ - -#define ARM_0_SEMS HW_REGISTER_RW(ARM_SBM_OWN0+0x00) -#define ARM_0_SEM0 HW_REGISTER_RW(ARM_SBM_OWN0+0x00) -#define ARM_0_SEM1 HW_REGISTER_RW(ARM_SBM_OWN0+0x04) -#define ARM_0_SEM2 HW_REGISTER_RW(ARM_SBM_OWN0+0x08) -#define ARM_0_SEM3 HW_REGISTER_RW(ARM_SBM_OWN0+0x0C) -#define ARM_0_SEM4 HW_REGISTER_RW(ARM_SBM_OWN0+0x10) -#define ARM_0_SEM5 HW_REGISTER_RW(ARM_SBM_OWN0+0x14) -#define ARM_0_SEM6 HW_REGISTER_RW(ARM_SBM_OWN0+0x18) -#define ARM_0_SEM7 HW_REGISTER_RW(ARM_SBM_OWN0+0x1C) -#define ARM_0_BELL0 HW_REGISTER_RW(ARM_SBM_OWN0+0x40) -#define ARM_0_BELL1 HW_REGISTER_RW(ARM_SBM_OWN0+0x44) -#define ARM_0_BELL2 HW_REGISTER_RW(ARM_SBM_OWN0+0x48) -#define ARM_0_BELL3 HW_REGISTER_RW(ARM_SBM_OWN0+0x4C) -/* MAILBOX 0 access in Owner 0 area */ -/* Some addresses should ONLY be used by owner 0 */ -#define ARM_0_MAIL0_WRT \ - HW_REGISTER_RW(ARM_SBM_OWN0+0x80) /* .. 0x8C (4 locations) */ -#define ARM_0_MAIL0_RD \ - HW_REGISTER_RW(ARM_SBM_OWN0+0x80) /* .. 0x8C (4 locs) Normal read */ -#define ARM_0_MAIL0_POL \ - HW_REGISTER_RW(ARM_SBM_OWN0+0x90) /* none-pop read */ -#define ARM_0_MAIL0_SND \ - HW_REGISTER_RW(ARM_SBM_OWN0+0x94) /* Sender read (only LS 2 bits) */ -#define ARM_0_MAIL0_STA \ - HW_REGISTER_RW(ARM_SBM_OWN0+0x98) /* Status read */ -#define ARM_0_MAIL0_CNF \ - HW_REGISTER_RW(ARM_SBM_OWN0+0x9C) /* Config read/write */ -/* MAILBOX 1 access in Owner 0 area */ -/* Owner 0 should only WRITE to this mailbox */ -#define ARM_0_MAIL1_WRT \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) /* .. 0xAC (4 locations) */ -/*#define ARM_0_MAIL1_RD \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_0_MAIL1_POL \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xB0) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_0_MAIL1_SND \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xB4) */ /* DO NOT USE THIS !!!!! */ -#define ARM_0_MAIL1_STA \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xB8) /* Status read */ -/*#define ARM_0_MAIL1_CNF \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xBC) */ /* DO NOT USE THIS !!!!! */ -/* General SEM, BELL, MAIL config/status */ -#define ARM_0_SEMCLRDBG \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xE0) /* semaphore clear/debug register */ -#define ARM_0_BELLCLRDBG \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xE4) /* Doorbells clear/debug register */ -#define ARM_0_ALL_IRQS \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xF8) /* ALL interrupts */ -#define ARM_0_MY_IRQS \ - HW_REGISTER_RW(ARM_SBM_OWN0+0xFC) /* IRQS pending for owner 0 */ - -/* Semaphores, Doorbells, Mailboxes Owner 1 */ -#define ARM_1_SEMS HW_REGISTER_RW(ARM_SBM_OWN1+0x00) -#define ARM_1_SEM0 HW_REGISTER_RW(ARM_SBM_OWN1+0x00) -#define ARM_1_SEM1 HW_REGISTER_RW(ARM_SBM_OWN1+0x04) -#define ARM_1_SEM2 HW_REGISTER_RW(ARM_SBM_OWN1+0x08) -#define ARM_1_SEM3 HW_REGISTER_RW(ARM_SBM_OWN1+0x0C) -#define ARM_1_SEM4 HW_REGISTER_RW(ARM_SBM_OWN1+0x10) -#define ARM_1_SEM5 HW_REGISTER_RW(ARM_SBM_OWN1+0x14) -#define ARM_1_SEM6 HW_REGISTER_RW(ARM_SBM_OWN1+0x18) -#define ARM_1_SEM7 HW_REGISTER_RW(ARM_SBM_OWN1+0x1C) -#define ARM_1_BELL0 HW_REGISTER_RW(ARM_SBM_OWN1+0x40) -#define ARM_1_BELL1 HW_REGISTER_RW(ARM_SBM_OWN1+0x44) -#define ARM_1_BELL2 HW_REGISTER_RW(ARM_SBM_OWN1+0x48) -#define ARM_1_BELL3 HW_REGISTER_RW(ARM_SBM_OWN1+0x4C) -/* MAILBOX 0 access in Owner 0 area */ -/* Owner 1 should only WRITE to this mailbox */ -#define ARM_1_MAIL0_WRT \ - HW_REGISTER_RW(ARM_SBM_OWN1+0x80) /* .. 0x8C (4 locations) */ -/*#define ARM_1_MAIL0_RD \ - HW_REGISTER_RW(ARM_SBM_OWN1+0x80) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_1_MAIL0_POL \ - HW_REGISTER_RW(ARM_SBM_OWN1+0x90) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_1_MAIL0_SND \ - HW_REGISTER_RW(ARM_SBM_OWN1+0x94) */ /* DO NOT USE THIS !!!!! */ -#define ARM_1_MAIL0_STA \ - HW_REGISTER_RW(ARM_SBM_OWN1+0x98) /* Status read */ -/*#define ARM_1_MAIL0_CNF \ - HW_REGISTER_RW(ARM_SBM_OWN1+0x9C) */ /* DO NOT USE THIS !!!!! */ -/* MAILBOX 1 access in Owner 0 area */ -#define ARM_1_MAIL1_WRT \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xA0) /* .. 0xAC (4 locations) */ -#define ARM_1_MAIL1_RD \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xA0) /* .. 0xAC (4 locs) Normal read */ -#define ARM_1_MAIL1_POL \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xB0) /* none-pop read */ -#define ARM_1_MAIL1_SND \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xB4) /* Sender read (only LS 2 bits) */ -#define ARM_1_MAIL1_STA \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xB8) /* Status read */ -#define ARM_1_MAIL1_CNF \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xBC) -/* General SEM, BELL, MAIL config/status */ -#define ARM_1_SEMCLRDBG \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xE0) /* semaphore clear/debug register */ -#define ARM_1_BELLCLRDBG \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xE4) /* Doorbells clear/debug register */ -#define ARM_1_MY_IRQS \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xFC) /* IRQS pending for owner 1 */ -#define ARM_1_ALL_IRQS \ - HW_REGISTER_RW(ARM_SBM_OWN1+0xF8) /* ALL interrupts */ - -/* Semaphores, Doorbells, Mailboxes Owner 2 */ -#define ARM_2_SEMS HW_REGISTER_RW(ARM_SBM_OWN2+0x00) -#define ARM_2_SEM0 HW_REGISTER_RW(ARM_SBM_OWN2+0x00) -#define ARM_2_SEM1 HW_REGISTER_RW(ARM_SBM_OWN2+0x04) -#define ARM_2_SEM2 HW_REGISTER_RW(ARM_SBM_OWN2+0x08) -#define ARM_2_SEM3 HW_REGISTER_RW(ARM_SBM_OWN2+0x0C) -#define ARM_2_SEM4 HW_REGISTER_RW(ARM_SBM_OWN2+0x10) -#define ARM_2_SEM5 HW_REGISTER_RW(ARM_SBM_OWN2+0x14) -#define ARM_2_SEM6 HW_REGISTER_RW(ARM_SBM_OWN2+0x18) -#define ARM_2_SEM7 HW_REGISTER_RW(ARM_SBM_OWN2+0x1C) -#define ARM_2_BELL0 HW_REGISTER_RW(ARM_SBM_OWN2+0x40) -#define ARM_2_BELL1 HW_REGISTER_RW(ARM_SBM_OWN2+0x44) -#define ARM_2_BELL2 HW_REGISTER_RW(ARM_SBM_OWN2+0x48) -#define ARM_2_BELL3 HW_REGISTER_RW(ARM_SBM_OWN2+0x4C) -/* MAILBOX 0 access in Owner 2 area */ -/* Owner 2 should only WRITE to this mailbox */ -#define ARM_2_MAIL0_WRT \ - HW_REGISTER_RW(ARM_SBM_OWN2+0x80) /* .. 0x8C (4 locations) */ -/*#define ARM_2_MAIL0_RD \ - HW_REGISTER_RW(ARM_SBM_OWN2+0x80) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_2_MAIL0_POL \ - HW_REGISTER_RW(ARM_SBM_OWN2+0x90) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_2_MAIL0_SND \ - HW_REGISTER_RW(ARM_SBM_OWN2+0x94) */ /* DO NOT USE THIS !!!!! */ -#define ARM_2_MAIL0_STA \ - HW_REGISTER_RW(ARM_SBM_OWN2+0x98) /* Status read */ -/*#define ARM_2_MAIL0_CNF \ - HW_REGISTER_RW(ARM_SBM_OWN2+0x9C) */ /* DO NOT USE THIS !!!!! */ -/* MAILBOX 1 access in Owner 2 area */ -/* Owner 2 should only WRITE to this mailbox */ -#define ARM_2_MAIL1_WRT \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) /* .. 0xAC (4 locations) */ -/*#define ARM_2_MAIL1_RD \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_2_MAIL1_POL \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xB0) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_2_MAIL1_SND \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xB4) */ /* DO NOT USE THIS !!!!! */ -#define ARM_2_MAIL1_STA \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xB8) /* Status read */ -/*#define ARM_2_MAIL1_CNF \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xBC) */ /* DO NOT USE THIS !!!!! */ -/* General SEM, BELL, MAIL config/status */ -#define ARM_2_SEMCLRDBG \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xE0) /* semaphore clear/debug register */ -#define ARM_2_BELLCLRDBG \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xE4) /* Doorbells clear/debug register */ -#define ARM_2_MY_IRQS \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xFC) /* IRQS pending for owner 2 */ -#define ARM_2_ALL_IRQS \ - HW_REGISTER_RW(ARM_SBM_OWN2+0xF8) /* ALL interrupts */ - -/* Semaphores, Doorbells, Mailboxes Owner 3 */ -#define ARM_3_SEMS HW_REGISTER_RW(ARM_SBM_OWN3+0x00) -#define ARM_3_SEM0 HW_REGISTER_RW(ARM_SBM_OWN3+0x00) -#define ARM_3_SEM1 HW_REGISTER_RW(ARM_SBM_OWN3+0x04) -#define ARM_3_SEM2 HW_REGISTER_RW(ARM_SBM_OWN3+0x08) -#define ARM_3_SEM3 HW_REGISTER_RW(ARM_SBM_OWN3+0x0C) -#define ARM_3_SEM4 HW_REGISTER_RW(ARM_SBM_OWN3+0x10) -#define ARM_3_SEM5 HW_REGISTER_RW(ARM_SBM_OWN3+0x14) -#define ARM_3_SEM6 HW_REGISTER_RW(ARM_SBM_OWN3+0x18) -#define ARM_3_SEM7 HW_REGISTER_RW(ARM_SBM_OWN3+0x1C) -#define ARM_3_BELL0 HW_REGISTER_RW(ARM_SBM_OWN3+0x40) -#define ARM_3_BELL1 HW_REGISTER_RW(ARM_SBM_OWN3+0x44) -#define ARM_3_BELL2 HW_REGISTER_RW(ARM_SBM_OWN3+0x48) -#define ARM_3_BELL3 HW_REGISTER_RW(ARM_SBM_OWN3+0x4C) -/* MAILBOX 0 access in Owner 3 area */ -/* Owner 3 should only WRITE to this mailbox */ -#define ARM_3_MAIL0_WRT \ - HW_REGISTER_RW(ARM_SBM_OWN3+0x80) /* .. 0x8C (4 locations) */ -/*#define ARM_3_MAIL0_RD \ - HW_REGISTER_RW(ARM_SBM_OWN3+0x80) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_3_MAIL0_POL \ - HW_REGISTER_RW(ARM_SBM_OWN3+0x90) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_3_MAIL0_SND \ - HW_REGISTER_RW(ARM_SBM_OWN3+0x94) */ /* DO NOT USE THIS !!!!! */ -#define ARM_3_MAIL0_STA \ - HW_REGISTER_RW(ARM_SBM_OWN3+0x98) /* Status read */ -/*#define ARM_3_MAIL0_CNF \ - HW_REGISTER_RW(ARM_SBM_OWN3+0x9C) */ /* DO NOT USE THIS !!!!! */ -/* MAILBOX 1 access in Owner 3 area */ -/* Owner 3 should only WRITE to this mailbox */ -#define ARM_3_MAIL1_WRT \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) /* .. 0xAC (4 locations) */ -/*#define ARM_3_MAIL1_RD \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_3_MAIL1_POL \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xB0) */ /* DO NOT USE THIS !!!!! */ -/*#define ARM_3_MAIL1_SND \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xB4) */ /* DO NOT USE THIS !!!!! */ -#define ARM_3_MAIL1_STA \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xB8) /* Status read */ -/*#define ARM_3_MAIL1_CNF \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xBC) */ /* DO NOT USE THIS !!!!! */ -/* General SEM, BELL, MAIL config/status */ -#define ARM_3_SEMCLRDBG \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xE0) /* semaphore clear/debug register */ -#define ARM_3_BELLCLRDBG \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xE4) /* Doorbells clear/debug register */ -#define ARM_3_MY_IRQS \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xFC) /* IRQS pending for owner 3 */ -#define ARM_3_ALL_IRQS \ - HW_REGISTER_RW(ARM_SBM_OWN3+0xF8) /* ALL interrupts */ - -/* Mailbox flags. Valid for all owners */ - -/* Mailbox status register (...0x98) */ -#define ARM_MS_FULL 0x80000000 -#define ARM_MS_EMPTY 0x40000000 -#define ARM_MS_LEVEL 0x400000FF /* Max. value depends on mailbox depth */ - -/* MAILBOX config/status register (...0x9C) */ -/* ANY write to this register clears the error bits! */ -#define ARM_MC_IHAVEDATAIRQEN 0x00000001 /* mbox irq enable: has data */ -#define ARM_MC_IHAVESPACEIRQEN 0x00000002 /* mbox irq enable: has space */ -#define ARM_MC_OPPISEMPTYIRQEN 0x00000004 /* mbox irq enable: Opp is empty */ -#define ARM_MC_MAIL_CLEAR 0x00000008 /* mbox clear write 1, then 0 */ -#define ARM_MC_IHAVEDATAIRQPEND 0x00000010 /* mbox irq pending: has space */ -#define ARM_MC_IHAVESPACEIRQPEND 0x00000020 /* mbox irq pending: Opp is empty */ -#define ARM_MC_OPPISEMPTYIRQPEND 0x00000040 /* mbox irq pending */ -/* Bit 7 is unused */ -#define ARM_MC_ERRNOOWN 0x00000100 /* error : none owner read from mailbox */ -#define ARM_MC_ERROVERFLW 0x00000200 /* error : write to fill mailbox */ -#define ARM_MC_ERRUNDRFLW 0x00000400 /* error : read from empty mailbox */ - -/* Semaphore clear/debug register (...0xE0) */ -#define ARM_SD_OWN0 0x00000003 /* Owner of sem 0 */ -#define ARM_SD_OWN1 0x0000000C /* Owner of sem 1 */ -#define ARM_SD_OWN2 0x00000030 /* Owner of sem 2 */ -#define ARM_SD_OWN3 0x000000C0 /* Owner of sem 3 */ -#define ARM_SD_OWN4 0x00000300 /* Owner of sem 4 */ -#define ARM_SD_OWN5 0x00000C00 /* Owner of sem 5 */ -#define ARM_SD_OWN6 0x00003000 /* Owner of sem 6 */ -#define ARM_SD_OWN7 0x0000C000 /* Owner of sem 7 */ -#define ARM_SD_SEM0 0x00010000 /* Status of sem 0 */ -#define ARM_SD_SEM1 0x00020000 /* Status of sem 1 */ -#define ARM_SD_SEM2 0x00040000 /* Status of sem 2 */ -#define ARM_SD_SEM3 0x00080000 /* Status of sem 3 */ -#define ARM_SD_SEM4 0x00100000 /* Status of sem 4 */ -#define ARM_SD_SEM5 0x00200000 /* Status of sem 5 */ -#define ARM_SD_SEM6 0x00400000 /* Status of sem 6 */ -#define ARM_SD_SEM7 0x00800000 /* Status of sem 7 */ - -/* Doorbells clear/debug register (...0xE4) */ -#define ARM_BD_OWN0 0x00000003 /* Owner of doorbell 0 */ -#define ARM_BD_OWN1 0x0000000C /* Owner of doorbell 1 */ -#define ARM_BD_OWN2 0x00000030 /* Owner of doorbell 2 */ -#define ARM_BD_OWN3 0x000000C0 /* Owner of doorbell 3 */ -#define ARM_BD_BELL0 0x00000100 /* Status of doorbell 0 */ -#define ARM_BD_BELL1 0x00000200 /* Status of doorbell 1 */ -#define ARM_BD_BELL2 0x00000400 /* Status of doorbell 2 */ -#define ARM_BD_BELL3 0x00000800 /* Status of doorbell 3 */ - -/* MY IRQS register (...0xF8) */ -#define ARM_MYIRQ_BELL 0x00000001 /* This owner has a doorbell IRQ */ -#define ARM_MYIRQ_MAIL 0x00000002 /* This owner has a mailbox IRQ */ - -/* ALL IRQS register (...0xF8) */ -#define ARM_AIS_BELL0 0x00000001 /* Doorbell 0 IRQ pending */ -#define ARM_AIS_BELL1 0x00000002 /* Doorbell 1 IRQ pending */ -#define ARM_AIS_BELL2 0x00000004 /* Doorbell 2 IRQ pending */ -#define ARM_AIS_BELL3 0x00000008 /* Doorbell 3 IRQ pending */ -#define ARM_AIS0_HAVEDATA 0x00000010 /* MAIL 0 has data IRQ pending */ -#define ARM_AIS0_HAVESPAC 0x00000020 /* MAIL 0 has space IRQ pending */ -#define ARM_AIS0_OPPEMPTY 0x00000040 /* MAIL 0 opposite is empty IRQ */ -#define ARM_AIS1_HAVEDATA 0x00000080 /* MAIL 1 has data IRQ pending */ -#define ARM_AIS1_HAVESPAC 0x00000100 /* MAIL 1 has space IRQ pending */ -#define ARM_AIS1_OPPEMPTY 0x00000200 /* MAIL 1 opposite is empty IRQ */ -/* Note that bell-0, bell-1 and MAIL0 IRQ go only to the ARM */ -/* Whilst that bell-2, bell-3 and MAIL1 IRQ go only to the VC */ -/* */ -/* ARM JTAG BASH */ -/* */ -#define AJB_BASE 0x7e2000c0 - -#define AJBCONF HW_REGISTER_RW(AJB_BASE+0x00) -#define AJB_BITS0 0x000000 -#define AJB_BITS4 0x000004 -#define AJB_BITS8 0x000008 -#define AJB_BITS12 0x00000C -#define AJB_BITS16 0x000010 -#define AJB_BITS20 0x000014 -#define AJB_BITS24 0x000018 -#define AJB_BITS28 0x00001C -#define AJB_BITS32 0x000020 -#define AJB_BITS34 0x000022 -#define AJB_OUT_MS 0x000040 -#define AJB_OUT_LS 0x000000 -#define AJB_INV_CLK 0x000080 -#define AJB_D0_RISE 0x000100 -#define AJB_D0_FALL 0x000000 -#define AJB_D1_RISE 0x000200 -#define AJB_D1_FALL 0x000000 -#define AJB_IN_RISE 0x000400 -#define AJB_IN_FALL 0x000000 -#define AJB_ENABLE 0x000800 -#define AJB_HOLD0 0x000000 -#define AJB_HOLD1 0x001000 -#define AJB_HOLD2 0x002000 -#define AJB_HOLD3 0x003000 -#define AJB_RESETN 0x004000 -#define AJB_CLKSHFT 16 -#define AJB_BUSY 0x80000000 -#define AJBTMS HW_REGISTER_RW(AJB_BASE+0x04) -#define AJBTDI HW_REGISTER_RW(AJB_BASE+0x08) -#define AJBTDO HW_REGISTER_RW(AJB_BASE+0x0c) - -#endif diff --git a/include/hw/arm/bcm2835_mbox.h b/include/hw/arm/bcm2835_mbox.h deleted file mode 100644 index b3977cd2b0..0000000000 --- a/include/hw/arm/bcm2835_mbox.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef BCM2835_MBOX_H -#define BCM2835_MBOX_H - -/* Constants shared with the ARM identifying separate mailbox channels */ -#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -#define MBOX_CHAN_COUNT 9 - -#define MBOX_SIZE 32 -#define MBOX_INVALID_DATA 0x0f - -#endif /* BCM2835_MBOX_H */ diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h old mode 100644 new mode 100755 index d9b92d29d9..037cc52667 --- a/include/hw/arm/bcm2835_peripherals.h +++ b/include/hw/arm/bcm2835_peripherals.h @@ -21,7 +21,7 @@ #include "hw/misc/bcm2835_mphi.h" #include "hw/misc/bcm2835_power.h" #include "hw/misc/bcm2835_property.h" -#include "hw/misc/bcm2835_sbm.h" +#include "hw/misc/bcm2835_mbox.h" #include "hw/misc/bcm2835_vchiq.h" #include "hw/sd/sdhci.h" #include "hw/timer/bcm2835_st.h" @@ -45,11 +45,11 @@ typedef struct BCM2835PeripheralState { BCM2835AuxState aux; BCM2835FbState fb; BCM2835DmaState dma; - BCM2835IcState ic; + BCM2835ICState ic; BCM2835MphiState mphi; BCM2835PowerState power; BCM2835PropertyState property; - BCM2835SbmState sbm; + BCM2835MboxState mboxes; BCM2835VchiqState vchiq; SDHCIState sdhci; BCM2835StState st; diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h old mode 100644 new mode 100755 index 4b094546fb..83869496e4 --- a/include/hw/arm/raspi_platform.h +++ b/include/hw/arm/raspi_platform.h @@ -41,7 +41,7 @@ #define IC0_OFFSET 0x2000 #define ST_OFFSET 0x3000 /* System Timer */ #define MPHI_OFFSET 0x6000 /* Message-based Parallel Host Intf. */ -#define DMA_OFFSET 0x7000 /* DMA controller */ +#define DMA_OFFSET 0x7000 /* DMA controller, channels 0-14 */ #define ARM_OFFSET 0xB000 /* BCM2708 ARM control block */ #define ARMCTRL_OFFSET (ARM_OFFSET + 0x000) #define ARMCTRL_IC_OFFSET (ARM_OFFSET + 0x200) /* Interrupt controller */ @@ -63,6 +63,7 @@ #define SMI_OFFSET 0x600000 /* SMI */ #define BSC1_OFFSET 0x804000 /* BSC1 I2C/TWI */ #define USB_OFFSET 0x980000 /* DTC_OTG USB controller */ +#define DMA15_OFFSET 0xE05000 /* DMA controller, channel 15 */ /* * Interrupt assignments diff --git a/include/hw/intc/bcm2835_ic.h b/include/hw/intc/bcm2835_ic.h old mode 100644 new mode 100755 index 428139d807..d897f44da1 --- a/include/hw/intc/bcm2835_ic.h +++ b/include/hw/intc/bcm2835_ic.h @@ -9,18 +9,25 @@ #include "hw/sysbus.h" #define TYPE_BCM2835_IC "bcm2835_ic" -#define BCM2835_IC(obj) OBJECT_CHECK(BCM2835IcState, (obj), TYPE_BCM2835_IC) +#define BCM2835_IC(obj) OBJECT_CHECK(BCM2835ICState, (obj), TYPE_BCM2835_IC) -typedef struct BCM2835IcState { +#define BCM2835_IC_GPU_IRQ "gpu-irq" +#define BCM2835_IC_ARM_IRQ "arm-irq" + +typedef struct BCM2835ICState { + /*< private >*/ SysBusDevice busdev; + /*< public >*/ + MemoryRegion iomem; - uint32_t level[3]; - uint32_t irq_enable[3]; - int fiq_enable; - int fiq_select; + /* 64 GPU IRQs + 8 ARM IRQs = 72 total (GPU first) */ + uint64_t gpu_irq_level, gpu_irq_enable; + uint8_t arm_irq_level, arm_irq_enable; + bool fiq_enable; + uint8_t fiq_select; qemu_irq irq; qemu_irq fiq; -} BCM2835IcState; +} BCM2835ICState; #endif diff --git a/include/hw/intc/bcm2836_control.h b/include/hw/intc/bcm2836_control.h old mode 100644 new mode 100755 index b6345cc7b5..8a9a2f2d24 --- a/include/hw/intc/bcm2836_control.h +++ b/include/hw/intc/bcm2836_control.h @@ -22,7 +22,9 @@ OBJECT_CHECK(BCM2836ControlState, (obj), TYPE_BCM2836_CONTROL) typedef struct BCM2836ControlState { + /*< private >*/ SysBusDevice busdev; + /*< public >*/ MemoryRegion iomem; /* interrupt status registers (not directly visible to user) */ diff --git a/include/hw/misc/bcm2835_sbm.h b/include/hw/misc/bcm2835_mbox.h similarity index 55% rename from include/hw/misc/bcm2835_sbm.h rename to include/hw/misc/bcm2835_mbox.h index da36fbe4f7..f24560cbed 100644 --- a/include/hw/misc/bcm2835_sbm.h +++ b/include/hw/misc/bcm2835_mbox.h @@ -3,35 +3,35 @@ * This code is licensed under the GNU GPLv2 and later. */ -#ifndef BCM2835_SBM_H -#define BCM2835_SBM_H +#ifndef BCM2835_MBOX_H +#define BCM2835_MBOX_H +#include "bcm2835_mbox_defs.h" #include "hw/sysbus.h" #include "exec/address-spaces.h" -#include "hw/arm/bcm2835_mbox.h" -#define TYPE_BCM2835_SBM "bcm2835_sbm" -#define BCM2835_SBM(obj) \ - OBJECT_CHECK(BCM2835SbmState, (obj), TYPE_BCM2835_SBM) +#define TYPE_BCM2835_MBOX "bcm2835_mbox" +#define BCM2835_MBOX(obj) \ + OBJECT_CHECK(BCM2835MboxState, (obj), TYPE_BCM2835_MBOX) typedef struct { - MemoryRegion *mbox_mr; - AddressSpace mbox_as; uint32_t reg[MBOX_SIZE]; - int count; + uint32_t count; uint32_t status; uint32_t config; } BCM2835Mbox; typedef struct { + /*< private >*/ SysBusDevice busdev; + /*< public >*/ MemoryRegion *mbox_mr; AddressSpace mbox_as; MemoryRegion iomem; - int mbox_irq_disabled; + bool mbox_irq_disabled; qemu_irq arm_irq; - int available[MBOX_CHAN_COUNT]; + bool available[MBOX_CHAN_COUNT]; BCM2835Mbox mbox[2]; -} BCM2835SbmState; +} BCM2835MboxState; #endif diff --git a/include/hw/misc/bcm2835_mbox_defs.h b/include/hw/misc/bcm2835_mbox_defs.h new file mode 100644 index 0000000000..48d8ee425f --- /dev/null +++ b/include/hw/misc/bcm2835_mbox_defs.h @@ -0,0 +1,26 @@ +/* + * Raspberry Pi emulation (c) 2012 Gregory Estrade + * This code is licensed under the GNU GPLv2 and later. + */ + +#ifndef BCM2835_MBOX_DEFS_H +#define BCM2835_MBOX_DEFS_H + +/* Constants shared with the ARM identifying separate mailbox channels */ +#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ +#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ +#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ +#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ +#define MBOX_CHAN_COUNT 9 + +#define MBOX_SIZE 32 +#define MBOX_INVALID_DATA 0x0f + +/* Layout of the private address space used for communication between + * the mbox device emulation, and child devices: each channel occupies + * 16 bytes of address space, but only two registers are presently defined. */ +#define MBOX_AS_CHAN_SHIFT 4 +#define MBOX_AS_DATA 0 /* request / response data (RW at offset 0) */ +#define MBOX_AS_PENDING 4 /* pending response status (RO at offset 4) */ + +#endif /* BCM2835_MBOX_DEFS_H */ diff --git a/include/hw/misc/bcm2835_property.h b/include/hw/misc/bcm2835_property.h old mode 100644 new mode 100755 index 6f43626f18..d452209a04 --- a/include/hw/misc/bcm2835_property.h +++ b/include/hw/misc/bcm2835_property.h @@ -15,13 +15,15 @@ OBJECT_CHECK(BCM2835PropertyState, (obj), TYPE_BCM2835_PROPERTY) typedef struct { + /*< private >*/ SysBusDevice busdev; + /*< public >*/ MemoryRegion *dma_mr; AddressSpace dma_as; BCM2835FbState *fbdev; MemoryRegion iomem; uint32_t addr; - int pending; + bool pending; qemu_irq mbox_irq; } BCM2835PropertyState; -- 2.11.4.GIT