From 2a257b4e22df120dd4a811012675158039a93c7d Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Thu, 2 Sep 2010 12:55:05 +0100 Subject: [PATCH] ios: Added a way to set and teardown modules IRQs Added a function to set the io module IRQ, and added a way to deallocate them at teardown time. Signed-off-by: Michel Pollet --- simavr/sim/sim_io.c | 31 ++++++++++++++++++++++++++++++- simavr/sim/sim_io.h | 10 ++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/simavr/sim/sim_io.c b/simavr/sim/sim_io.c index 63862e2..42e8c1b 100644 --- a/simavr/sim/sim_io.c +++ b/simavr/sim/sim_io.c @@ -70,7 +70,6 @@ struct avr_irq_t * avr_io_getirq(avr_t * avr, uint32_t ctl, int index) } - avr_irq_t * avr_iomem_getirq(avr_t * avr, avr_io_addr_t addr, int index) { avr_io_addr_t a = AVR_DATA_TO_IO(addr); @@ -83,3 +82,33 @@ avr_irq_t * avr_iomem_getirq(avr_t * avr, avr_io_addr_t addr, int index) return index < 9 ? avr->io[a].irq + index : NULL; } +struct avr_irq_t * avr_io_setirqs(avr_io_t * io, uint32_t ctl, int count, struct avr_irq_t * irqs) +{ + // allocate this module's IRQ + io->irq_count = count; + io->irq = irqs ? irqs : avr_alloc_irq(0, count); + io->irq_ioctl_get = ctl; + return io->irq; +} + +static void avr_deallocate_io(avr_io_t * io) +{ + if (io->dealloc) + io->dealloc(io); + avr_free_irq(io->irq, io->irq_count); + io->irq_count = 0; + io->irq_ioctl_get = 0; + io->avr = NULL; + io->next = NULL; +} + +void avr_deallocate_ios(avr_t * avr) +{ + avr_io_t * port = avr->io_port; + while (port) { + avr_io_t * next = port->next; + avr_deallocate_io(port); + port = next; + } + avr->io_port = NULL; +} diff --git a/simavr/sim/sim_io.h b/simavr/sim/sim_io.h index 8fa338d..e165678 100644 --- a/simavr/sim/sim_io.h +++ b/simavr/sim/sim_io.h @@ -53,6 +53,9 @@ typedef struct avr_io_t { void (*reset)(struct avr_io_t *io); // called externally. allow access to io modules and so on int (*ioctl)(struct avr_io_t *io, uint32_t ctl, void *io_param); + + // optional, a function to free up allocated system resources + void (*dealloc)(struct avr_io_t *io); } avr_io_t; /* @@ -63,6 +66,10 @@ typedef struct avr_io_t { // this is called by the AVR core init functions, you /could/ register an external // one after instanciation, for whatever purpose... void avr_register_io(avr_t *avr, avr_io_t * io); +// Sets an IO module "official" IRQs and the ioctl used to get to them. if 'irqs' is NULL, +// 'count' will be allocated +struct avr_irq_t * avr_io_setirqs(avr_io_t * io, uint32_t ctl, int count, struct avr_irq_t * irqs); + // register a callback for when IO register "addr" is read void avr_register_io_read(avr_t *avr, avr_io_addr_t addr, avr_io_read_t read, void * param); // register a callback for when the IO register is written. callback has to set the memory itself @@ -82,6 +89,9 @@ struct avr_irq_t * avr_io_getirq(avr_t * avr, uint32_t ctl, int index); #define AVR_IOMEM_IRQ_ALL 8 struct avr_irq_t * avr_iomem_getirq(avr_t * avr, avr_io_addr_t addr, int index); +// Terminates all IOs and remove from them from the io chain +void avr_deallocate_ios(avr_t *avr); + #ifdef __cplusplus }; #endif -- 2.39.5