hw/sparc: Make grlib-irqmp device handle its own inbound IRQ lines
Currently the GRLIB_IRQMP device is used in one place (the leon3 board), but instead of the device providing inbound gpio lines for the board to wire up, the board code itself calls qemu_allocate_irqs() with the handler function being a set_irq function defined in the code for the device. Refactor this into the standard setup of a device having input gpio lines. This fixes a trivial Coverity memory leak report (the leon3 board code leaks the IRQ array returned from qemu_allocate_irqs()). Fixes: Coverity CID 1421922 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20201212144134.29594-2-peter.maydell@linaro.org> Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This commit is contained in:
parent
62a9b228b5
commit
3391953660
@ -51,6 +51,8 @@
|
|||||||
#define FORCE_OFFSET 0x80
|
#define FORCE_OFFSET 0x80
|
||||||
#define EXTENDED_OFFSET 0xC0
|
#define EXTENDED_OFFSET 0xC0
|
||||||
|
|
||||||
|
#define MAX_PILS 16
|
||||||
|
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(IRQMP, GRLIB_IRQMP)
|
OBJECT_DECLARE_SIMPLE_TYPE(IRQMP, GRLIB_IRQMP)
|
||||||
|
|
||||||
typedef struct IRQMPState IRQMPState;
|
typedef struct IRQMPState IRQMPState;
|
||||||
@ -126,7 +128,7 @@ void grlib_irqmp_ack(DeviceState *dev, int intno)
|
|||||||
grlib_irqmp_ack_mask(state, mask);
|
grlib_irqmp_ack_mask(state, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void grlib_irqmp_set_irq(void *opaque, int irq, int level)
|
static void grlib_irqmp_set_irq(void *opaque, int irq, int level)
|
||||||
{
|
{
|
||||||
IRQMP *irqmp = GRLIB_IRQMP(opaque);
|
IRQMP *irqmp = GRLIB_IRQMP(opaque);
|
||||||
IRQMPState *s;
|
IRQMPState *s;
|
||||||
@ -328,6 +330,7 @@ static void grlib_irqmp_init(Object *obj)
|
|||||||
IRQMP *irqmp = GRLIB_IRQMP(obj);
|
IRQMP *irqmp = GRLIB_IRQMP(obj);
|
||||||
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
|
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
|
||||||
|
|
||||||
|
qdev_init_gpio_in(DEVICE(obj), grlib_irqmp_set_irq, MAX_PILS);
|
||||||
qdev_init_gpio_out_named(DEVICE(obj), &irqmp->irq, "grlib-irq", 1);
|
qdev_init_gpio_out_named(DEVICE(obj), &irqmp->irq, "grlib-irq", 1);
|
||||||
memory_region_init_io(&irqmp->iomem, obj, &grlib_irqmp_ops, irqmp,
|
memory_region_init_io(&irqmp->iomem, obj, &grlib_irqmp_ops, irqmp,
|
||||||
"irqmp", IRQMP_REG_SIZE);
|
"irqmp", IRQMP_REG_SIZE);
|
||||||
|
@ -52,8 +52,6 @@
|
|||||||
#define LEON3_PROM_OFFSET (0x00000000)
|
#define LEON3_PROM_OFFSET (0x00000000)
|
||||||
#define LEON3_RAM_OFFSET (0x40000000)
|
#define LEON3_RAM_OFFSET (0x40000000)
|
||||||
|
|
||||||
#define MAX_PILS 16
|
|
||||||
|
|
||||||
#define LEON3_UART_OFFSET (0x80000100)
|
#define LEON3_UART_OFFSET (0x80000100)
|
||||||
#define LEON3_UART_IRQ (3)
|
#define LEON3_UART_IRQ (3)
|
||||||
|
|
||||||
@ -194,11 +192,10 @@ static void leon3_generic_hw_init(MachineState *machine)
|
|||||||
MemoryRegion *prom = g_new(MemoryRegion, 1);
|
MemoryRegion *prom = g_new(MemoryRegion, 1);
|
||||||
int ret;
|
int ret;
|
||||||
char *filename;
|
char *filename;
|
||||||
qemu_irq *cpu_irqs = NULL;
|
|
||||||
int bios_size;
|
int bios_size;
|
||||||
int prom_size;
|
int prom_size;
|
||||||
ResetData *reset_info;
|
ResetData *reset_info;
|
||||||
DeviceState *dev;
|
DeviceState *dev, *irqmpdev;
|
||||||
int i;
|
int i;
|
||||||
AHBPnp *ahb_pnp;
|
AHBPnp *ahb_pnp;
|
||||||
APBPnp *apb_pnp;
|
APBPnp *apb_pnp;
|
||||||
@ -230,16 +227,15 @@ static void leon3_generic_hw_init(MachineState *machine)
|
|||||||
GRLIB_AHB_SLAVE, GRLIB_AHBMEM_AREA);
|
GRLIB_AHB_SLAVE, GRLIB_AHBMEM_AREA);
|
||||||
|
|
||||||
/* Allocate IRQ manager */
|
/* Allocate IRQ manager */
|
||||||
dev = qdev_new(TYPE_GRLIB_IRQMP);
|
irqmpdev = qdev_new(TYPE_GRLIB_IRQMP);
|
||||||
qdev_init_gpio_in_named_with_opaque(DEVICE(cpu), leon3_set_pil_in,
|
qdev_init_gpio_in_named_with_opaque(DEVICE(cpu), leon3_set_pil_in,
|
||||||
env, "pil", 1);
|
env, "pil", 1);
|
||||||
qdev_connect_gpio_out_named(dev, "grlib-irq", 0,
|
qdev_connect_gpio_out_named(irqmpdev, "grlib-irq", 0,
|
||||||
qdev_get_gpio_in_named(DEVICE(cpu), "pil", 0));
|
qdev_get_gpio_in_named(DEVICE(cpu), "pil", 0));
|
||||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(irqmpdev), &error_fatal);
|
||||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, LEON3_IRQMP_OFFSET);
|
sysbus_mmio_map(SYS_BUS_DEVICE(irqmpdev), 0, LEON3_IRQMP_OFFSET);
|
||||||
env->irq_manager = dev;
|
env->irq_manager = irqmpdev;
|
||||||
env->qemu_irq_ack = leon3_irq_manager;
|
env->qemu_irq_ack = leon3_irq_manager;
|
||||||
cpu_irqs = qemu_allocate_irqs(grlib_irqmp_set_irq, dev, MAX_PILS);
|
|
||||||
grlib_apb_pnp_add_entry(apb_pnp, LEON3_IRQMP_OFFSET, 0xFFF,
|
grlib_apb_pnp_add_entry(apb_pnp, LEON3_IRQMP_OFFSET, 0xFFF,
|
||||||
GRLIB_VENDOR_GAISLER, GRLIB_IRQMP_DEV,
|
GRLIB_VENDOR_GAISLER, GRLIB_IRQMP_DEV,
|
||||||
2, 0, GRLIB_APBIO_AREA);
|
2, 0, GRLIB_APBIO_AREA);
|
||||||
@ -330,7 +326,7 @@ static void leon3_generic_hw_init(MachineState *machine)
|
|||||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, LEON3_TIMER_OFFSET);
|
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, LEON3_TIMER_OFFSET);
|
||||||
for (i = 0; i < LEON3_TIMER_COUNT; i++) {
|
for (i = 0; i < LEON3_TIMER_COUNT; i++) {
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
|
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
|
||||||
cpu_irqs[LEON3_TIMER_IRQ + i]);
|
qdev_get_gpio_in(irqmpdev, LEON3_TIMER_IRQ + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
grlib_apb_pnp_add_entry(apb_pnp, LEON3_TIMER_OFFSET, 0xFFF,
|
grlib_apb_pnp_add_entry(apb_pnp, LEON3_TIMER_OFFSET, 0xFFF,
|
||||||
@ -342,7 +338,8 @@ static void leon3_generic_hw_init(MachineState *machine)
|
|||||||
qdev_prop_set_chr(dev, "chrdev", serial_hd(0));
|
qdev_prop_set_chr(dev, "chrdev", serial_hd(0));
|
||||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
||||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, LEON3_UART_OFFSET);
|
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, LEON3_UART_OFFSET);
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irqs[LEON3_UART_IRQ]);
|
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
|
||||||
|
qdev_get_gpio_in(irqmpdev, LEON3_UART_IRQ));
|
||||||
grlib_apb_pnp_add_entry(apb_pnp, LEON3_UART_OFFSET, 0xFFF,
|
grlib_apb_pnp_add_entry(apb_pnp, LEON3_UART_OFFSET, 0xFFF,
|
||||||
GRLIB_VENDOR_GAISLER, GRLIB_APBUART_DEV, 1,
|
GRLIB_VENDOR_GAISLER, GRLIB_APBUART_DEV, 1,
|
||||||
LEON3_UART_IRQ, GRLIB_APBIO_AREA);
|
LEON3_UART_IRQ, GRLIB_APBIO_AREA);
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
|
|
||||||
typedef void (*set_pil_in_fn) (void *opaque, uint32_t pil_in);
|
typedef void (*set_pil_in_fn) (void *opaque, uint32_t pil_in);
|
||||||
|
|
||||||
void grlib_irqmp_set_irq(void *opaque, int irq, int level);
|
|
||||||
|
|
||||||
void grlib_irqmp_ack(DeviceState *dev, int intno);
|
void grlib_irqmp_ack(DeviceState *dev, int intno);
|
||||||
|
|
||||||
/* GPTimer */
|
/* GPTimer */
|
||||||
|
Loading…
Reference in New Issue
Block a user