From 4ca5fe4e37ff264a11d83331df1efd552887fe22 Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Tue, 22 Feb 2011 23:20:36 +0000 Subject: [PATCH] irq: Add names to most io module external irqs Nothing to be shown for this work so far, the cool stuff hopefully will come later... Signed-off-by: Michel Pollet --- simavr/sim/avr_adc.c | 15 +++++++++++ simavr/sim/avr_adc.h | 2 +- simavr/sim/avr_extint.c | 12 +++++++++ simavr/sim/avr_extint.h | 2 +- simavr/sim/avr_ioport.c | 16 +++++++++++- simavr/sim/avr_spi.c | 6 +++++ simavr/sim/avr_timer.c | 9 +++++++ simavr/sim/avr_uart.c | 8 ++++++ simavr/sim/sim_io.c | 58 +++++++++++++++++++++++++++++++++++++---- simavr/sim/sim_io.h | 4 ++- simavr/sim/sim_irq.c | 39 +++++++++++++++++++++++++-- 11 files changed, 160 insertions(+), 11 deletions(-) diff --git a/simavr/sim/avr_adc.c b/simavr/sim/avr_adc.c index 3e010c9..f2b2606 100644 --- a/simavr/sim/avr_adc.c +++ b/simavr/sim/avr_adc.c @@ -212,9 +212,24 @@ static void avr_adc_reset(avr_io_t * port) avr_irq_register_notify(p->io.irq + i, avr_adc_irq_notify, p); } +static const char * irq_names[ADC_IRQ_COUNT] = { + [ADC_IRQ_ADC0] = "16io.irq + SPI_IRQ_INPUT, avr_spi_irq_input, p); } +static const char * irq_names[SPI_IRQ_COUNT] = { + [SPI_IRQ_INPUT] = "8 #include #include +#include #include "sim_io.h" int @@ -160,7 +161,7 @@ avr_iomem_getirq( { avr_io_addr_t a = AVR_DATA_TO_IO(addr); if (avr->io[a].irq == NULL) { - avr->io[a].irq = avr_alloc_irq(&avr->irq_pool, 0, 9, NULL /* TODO: names*/); + avr->io[a].irq = avr_alloc_irq(&avr->irq_pool, 0, 9, NULL); // mark the pin ones as filtered, so they only are raised when changing for (int i = 0; i < 8; i++) avr->io[a].irq[i].flags |= IRQ_FLAG_FILTERED; @@ -173,13 +174,60 @@ avr_io_setirqs( avr_io_t * io, uint32_t ctl, int count, - avr_irq_t * irqs) + avr_irq_t * irqs ) { // allocate this module's IRQ io->irq_count = count; - io->irq = irqs ? irqs : - avr_alloc_irq(&io->avr->irq_pool, 0, - count, NULL /* TODO: names*/); + + if (!irqs) { + const char ** irq_names = NULL; + + if (io->irq_names) { + irq_names = malloc(count * sizeof(char*)); + memset(irq_names, 0, count * sizeof(char*)); + char buf[64]; + for (int i = 0; i < count; i++) { + /* + * this bit takes the io module 'kind' ("port") + * the IRQ name ("=0") and the last character of the ioctl ('p','o','r','A') + * to create a full name "=porta.0" + */ + char * dst = buf; + // copy the 'flags' of the name out + const char * kind = io->irq_names[i]; + while (!isalpha(*kind)) + *dst++ = *kind++; + // add avr name +// strcpy(dst, io->avr->mmcu); + strcpy(dst, "avr"); + dst += strlen(dst); + *dst ++ = '.'; + // add module 'kind' + strcpy(dst, io->kind); + dst += strlen(dst); + // add port name, if any + if ((ctl & 0xff) > ' ') + *dst ++ = tolower(ctl & 0xff); + *dst ++ = '.'; + // add the rest of the irq name + strcpy(dst, kind); + dst += strlen(dst); + *dst = 0; + +// printf("%s\n", buf); + irq_names[i] = strdup(buf); + } + } + irqs = avr_alloc_irq(&io->avr->irq_pool, 0, + count, irq_names); + if (irq_names) { + for (int i = 0; i < count; i++) + free((char*)irq_names[i]); + free((char*)irq_names); + } + } + + io->irq = irqs; io->irq_ioctl_get = ctl; return io->irq; } diff --git a/simavr/sim/sim_io.h b/simavr/sim/sim_io.h index aa29a29..c3f01e5 100644 --- a/simavr/sim/sim_io.h +++ b/simavr/sim/sim_io.h @@ -44,6 +44,8 @@ typedef struct avr_io_t { avr_t * avr; // avr we are attached to const char * kind; // pretty name, for debug + const char ** irq_names; // IRQ names + uint32_t irq_ioctl_get; // used to get irqs from this module int irq_count; // number of (optional) irqs struct avr_irq_t * irq; // optional external IRQs @@ -74,7 +76,7 @@ avr_io_setirqs( avr_io_t * io, uint32_t ctl, int count, - avr_irq_t * irqs); + avr_irq_t * irqs ); // register a callback for when IO register "addr" is read void diff --git a/simavr/sim/sim_irq.c b/simavr/sim/sim_irq.c index 6e69540..634ea9c 100644 --- a/simavr/sim/sim_irq.c +++ b/simavr/sim/sim_irq.c @@ -34,6 +34,31 @@ typedef struct avr_irq_hook_t { void * param; // "notify" parameter } avr_irq_hook_t; +static void +_avr_irq_pool_add( + avr_irq_pool_t * pool, + avr_irq_t * irq) +{ + if ((pool->count & 0xf) == 0) { + pool->irq = (avr_irq_t**)realloc(pool->irq, + (pool->count + 16) * sizeof(avr_irq_t *)); + } + pool->irq[pool->count++] = irq; + irq->pool = pool; +} + +static void +_avr_irq_pool_remove( + avr_irq_pool_t * pool, + avr_irq_t * irq) +{ + for (int i = 0; i < pool->count; i++) + if (pool->irq[i] == irq) { + pool->irq[i] = 0; + return; + } +} + void avr_init_irq( avr_irq_pool_t * pool, @@ -46,6 +71,10 @@ avr_init_irq( for (int i = 0; i < count; i++) { irq[i].irq = base + i; + if (pool) + _avr_irq_pool_add(pool, &irq[i]); + if (names && names[i]) + irq[i].name = strdup(names[i]); } } @@ -82,14 +111,20 @@ avr_free_irq( if (!irq || !count) return; for (int i = 0; i < count; i++) { + avr_irq_t * iq = irq + i; + if (iq->pool) + _avr_irq_pool_remove(iq->pool, iq); + if (iq->name) + free((char*)iq->name); + iq->name = NULL; // purge hooks - avr_irq_hook_t *hook = irq->hook; + avr_irq_hook_t *hook = iq->hook; while (hook) { avr_irq_hook_t * next = hook->next; free(hook); hook = next; } - irq->hook = NULL; + iq->hook = NULL; } // if that irq list was allocated by us, free it if (irq->flags & IRQ_FLAG_ALLOC) -- 2.39.5