* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "cpu.h"
#include "hw/sparc/grlib.h"
#include "trace.h"
+#include "qapi/error.h"
#define IRQMP_MAX_CPU 16
#define IRQMP_REG_SIZE 256 /* Size of memory mapped registers */
#define FORCE_OFFSET 0x80
#define EXTENDED_OFFSET 0xC0
+#define TYPE_GRLIB_IRQMP "grlib,irqmp"
+#define GRLIB_IRQMP(obj) OBJECT_CHECK(IRQMP, (obj), TYPE_GRLIB_IRQMP)
+
typedef struct IRQMPState IRQMPState;
typedef struct IRQMP {
- SysBusDevice busdev;
+ SysBusDevice parent_obj;
+
MemoryRegion iomem;
void *set_pil_in;
}
}
+static void grlib_irqmp_ack_mask(IRQMPState *state, uint32_t mask)
+{
+ /* Clear registers */
+ state->pending &= ~mask;
+ state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
+
+ grlib_irqmp_check_irqs(state);
+}
+
void grlib_irqmp_ack(DeviceState *dev, int intno)
{
- SysBusDevice *sdev;
- IRQMP *irqmp;
+ IRQMP *irqmp = GRLIB_IRQMP(dev);
IRQMPState *state;
uint32_t mask;
- assert(dev != NULL);
-
- sdev = SYS_BUS_DEVICE(dev);
- assert(sdev != NULL);
-
- irqmp = FROM_SYSBUS(typeof(*irqmp), sdev);
- assert(irqmp != NULL);
-
state = irqmp->state;
assert(state != NULL);
trace_grlib_irqmp_ack(intno);
- /* Clear registers */
- state->pending &= ~mask;
- state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
-
- grlib_irqmp_check_irqs(state);
+ grlib_irqmp_ack_mask(state, mask);
}
void grlib_irqmp_set_irq(void *opaque, int irq, int level)
{
- IRQMP *irqmp;
+ IRQMP *irqmp = GRLIB_IRQMP(opaque);
IRQMPState *s;
int i = 0;
- assert(opaque != NULL);
-
- irqmp = FROM_SYSBUS(typeof(*irqmp), SYS_BUS_DEVICE(opaque));
- assert(irqmp != NULL);
-
s = irqmp->state;
assert(s != NULL);
assert(s->parent != NULL);
case CLEAR_OFFSET:
value &= ~1; /* clean up the value */
- state->pending &= ~value;
+ grlib_irqmp_ack_mask(state, value);
return;
case MP_STATUS_OFFSET:
static void grlib_irqmp_reset(DeviceState *d)
{
- IRQMP *irqmp = container_of(d, IRQMP, busdev.qdev);
- assert(irqmp != NULL);
+ IRQMP *irqmp = GRLIB_IRQMP(d);
assert(irqmp->state != NULL);
memset(irqmp->state, 0, sizeof *irqmp->state);
irqmp->state->parent = irqmp;
}
-static int grlib_irqmp_init(SysBusDevice *dev)
+static void grlib_irqmp_init(Object *obj)
{
- IRQMP *irqmp = FROM_SYSBUS(typeof(*irqmp), dev);
-
- assert(irqmp != NULL);
-
- /* Check parameters */
- if (irqmp->set_pil_in == NULL) {
- return -1;
- }
+ IRQMP *irqmp = GRLIB_IRQMP(obj);
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
- memory_region_init_io(&irqmp->iomem, OBJECT(dev), &grlib_irqmp_ops, irqmp,
+ memory_region_init_io(&irqmp->iomem, obj, &grlib_irqmp_ops, irqmp,
"irqmp", IRQMP_REG_SIZE);
irqmp->state = g_malloc0(sizeof *irqmp->state);
sysbus_init_mmio(dev, &irqmp->iomem);
+}
- return 0;
+static void grlib_irqmp_realize(DeviceState *dev, Error **errp)
+{
+ IRQMP *irqmp = GRLIB_IRQMP(dev);
+
+ /* Check parameters */
+ if (irqmp->set_pil_in == NULL) {
+ error_setg(errp, "set_pil_in cannot be NULL.");
+ }
}
static Property grlib_irqmp_properties[] = {
static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = grlib_irqmp_init;
dc->reset = grlib_irqmp_reset;
dc->props = grlib_irqmp_properties;
+ /* Reason: pointer properties "set_pil_in", "set_pil_in_opaque" */
+ dc->user_creatable = false;
+ dc->realize = grlib_irqmp_realize;
}
static const TypeInfo grlib_irqmp_info = {
- .name = "grlib,irqmp",
+ .name = TYPE_GRLIB_IRQMP,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(IRQMP),
+ .instance_init = grlib_irqmp_init,
.class_init = grlib_irqmp_class_init,
};