xemu/hw/intc/bcm2835_ic.c
Bernhard Beschow 5e78c98b7c Mark remaining global TypeInfo instances as const
More than 1k of TypeInfo instances are already marked as const. Mark the
remaining ones, too.

This commit was created with:
  git grep -z -l 'static TypeInfo' -- '*.c' | \
  xargs -0 sed -i 's/static TypeInfo/static const TypeInfo/'

Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Corey Minyard <cminyard@mvista.com>
Message-id: 20220117145805.173070-2-shentey@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2022-02-21 13:30:20 +00:00

244 lines
6.9 KiB
C

/*
* Raspberry Pi emulation (c) 2012 Gregory Estrade
* Refactoring for Pi2 Copyright (c) 2015, Microsoft. Written by Andrew Baumann.
* Heavily based on pl190.c, copyright terms below:
*
* Arm PrimeCell PL190 Vector Interrupt Controller
*
* Copyright (c) 2006 CodeSourcery.
* Written by Paul Brook
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "hw/intc/bcm2835_ic.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.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);
trace_bcm2835_ic_set_gpu_irq(irq, level);
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);
trace_bcm2835_ic_set_cpu_irq(irq, level);
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:
res = gpu_pending;
break;
case IRQ_PENDING_2:
res = gpu_pending >> 32;
break;
case FIQ_CONTROL:
res = (s->fiq_enable << 7) | s->fiq_select;
break;
case IRQ_ENABLE_1:
res = s->gpu_irq_enable;
break;
case IRQ_ENABLE_2:
res = s->gpu_irq_enable >> 32;
break;
case IRQ_ENABLE_BASIC:
res = s->arm_irq_enable;
break;
case IRQ_DISABLE_1:
res = ~s->gpu_irq_enable;
break;
case IRQ_DISABLE_2:
res = ~s->gpu_irq_enable >> 32;
break;
case IRQ_DISABLE_BASIC:
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 = extract32(val, 0, 7);
s->fiq_enable = extract32(val, 7, 1);
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 const 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)