From 4462c22a8cc1a77ed592b0fac3d227850c5cd86a Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Tue, 22 Feb 2011 17:23:54 +0000 Subject: [PATCH] irq: Introduce a "irq pool" The goal is to be able to name IRQs, so a couple fields are added. It is not functional for now, as the task is to first convert all the code to the new prototype. Also introduce a 2011 way of formatting prototypes Signed-off-by: Michel Pollet --- simavr/sim/sim_irq.c | 45 +++++++++++++++++++----- simavr/sim/sim_irq.h | 81 ++++++++++++++++++++++++++++++++------------ 2 files changed, 95 insertions(+), 31 deletions(-) diff --git a/simavr/sim/sim_irq.c b/simavr/sim/sim_irq.c index 92c2c17..6e69540 100644 --- a/simavr/sim/sim_irq.c +++ b/simavr/sim/sim_irq.c @@ -34,24 +34,38 @@ typedef struct avr_irq_hook_t { void * param; // "notify" parameter } avr_irq_hook_t; -void avr_init_irq(avr_irq_t * irq, uint32_t base, uint32_t count) +void +avr_init_irq( + avr_irq_pool_t * pool, + avr_irq_t * irq, + uint32_t base, + uint32_t count, + const char ** names /* optional */) { memset(irq, 0, sizeof(avr_irq_t) * count); - for (int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { irq[i].irq = base + i; + } } -avr_irq_t * avr_alloc_irq(uint32_t base, uint32_t count) +avr_irq_t * +avr_alloc_irq( + avr_irq_pool_t * pool, + uint32_t base, + uint32_t count, + const char ** names /* optional */) { avr_irq_t * irq = (avr_irq_t*)malloc(sizeof(avr_irq_t) * count); - avr_init_irq(irq, base, count); + avr_init_irq(pool, irq, base, count, names); for (int i = 0; i < count; i++) irq[i].flags |= IRQ_FLAG_ALLOC; return irq; } -static avr_irq_hook_t * _avr_alloc_irq_hook(avr_irq_t * irq) +static avr_irq_hook_t * +_avr_alloc_irq_hook( + avr_irq_t * irq) { avr_irq_hook_t *hook = malloc(sizeof(avr_irq_hook_t)); memset(hook, 0, sizeof(avr_irq_hook_t)); @@ -60,7 +74,10 @@ static avr_irq_hook_t * _avr_alloc_irq_hook(avr_irq_t * irq) return hook; } -void avr_free_irq(avr_irq_t * irq, uint32_t count) +void +avr_free_irq( + avr_irq_t * irq, + uint32_t count) { if (!irq || !count) return; @@ -79,7 +96,11 @@ void avr_free_irq(avr_irq_t * irq, uint32_t count) free(irq); } -void avr_irq_register_notify(avr_irq_t * irq, avr_irq_notify_t notify, void * param) +void +avr_irq_register_notify( + avr_irq_t * irq, + avr_irq_notify_t notify, + void * param) { if (!irq || !notify) return; @@ -95,7 +116,10 @@ void avr_irq_register_notify(avr_irq_t * irq, avr_irq_notify_t notify, void * pa hook->param = param; } -void avr_raise_irq(avr_irq_t * irq, uint32_t value) +void +avr_raise_irq( + avr_irq_t * irq, + uint32_t value) { if (!irq) return ; @@ -122,7 +146,10 @@ void avr_raise_irq(avr_irq_t * irq, uint32_t value) irq->value = output; } -void avr_connect_irq(avr_irq_t * src, avr_irq_t * dst) +void +avr_connect_irq( + avr_irq_t * src, + avr_irq_t * dst) { if (!src || !dst || src == dst) { printf("avr_connect_irq invalid irq %p/%p", src, dst); diff --git a/simavr/sim/sim_irq.h b/simavr/sim/sim_irq.h index d7a9db0..6f4be93 100644 --- a/simavr/sim/sim_irq.h +++ b/simavr/sim/sim_irq.h @@ -33,10 +33,10 @@ extern "C" { * * This subsystem allow any piece of code to "register" a hook to be called when an IRQ is * raised. The IRQ definition is up to the module defining it, for example a IOPORT pin change - * might be an IRQ in wich case any oiece of code can be notified when a pin has changed state + * might be an IRQ in which case any piece of code can be notified when a pin has changed state * * The notify hooks are chained, and duplicates are filtered out so you can't register a - * notify hook twice on one particylar IRQ + * notify hook twice on one particular IRQ * * IRQ calling order is not defined, so don't rely on it. * @@ -45,37 +45,74 @@ extern "C" { */ struct avr_irq_t; -typedef void (*avr_irq_notify_t)(struct avr_irq_t * irq, uint32_t value, void * param); +typedef void (*avr_irq_notify_t)( + struct avr_irq_t * irq, + uint32_t value, + void * param); enum { - IRQ_FLAG_NOT = (1 << 0), // change polarity of the IRQ - IRQ_FLAG_FILTERED = (1 << 1), // do not "notify" if "value" is the same as previous raise - IRQ_FLAG_ALLOC = (1 << 2), // this irq structure was malloced via avr_alloc_irq + IRQ_FLAG_NOT = (1 << 0), //!< change polarity of the IRQ + IRQ_FLAG_FILTERED = (1 << 1), //!< do not "notify" if "value" is the same as previous raise + IRQ_FLAG_ALLOC = (1 << 2), //!< this irq structure was malloced via avr_alloc_irq }; /* + * IRQ Pool structure + */ +typedef struct avr_irq_pool_t { + int count; //!< number of irqs living in the pool + struct avr_irq_t ** irq; //!< irqs belongging in this pool +} avr_irq_pool_t; + +/*! * Public IRQ structure */ typedef struct avr_irq_t { - uint32_t irq; // any value the user needs - uint32_t value; // current value - uint8_t flags; // IRQ_* flags - struct avr_irq_hook_t * hook; // list of hooks to be notified + struct avr_irq_pool_t * pool; // TODO: migration in progress + const char * name; + uint32_t irq; //!< any value the user needs + uint32_t value; //!< current value + uint8_t flags; //!< IRQ_* flags + struct avr_irq_hook_t * hook; //!< list of hooks to be notified } avr_irq_t; -// allocates 'count' IRQs, initializes their "irq" starting from 'base' and increment -avr_irq_t * avr_alloc_irq(uint32_t base, uint32_t count); -void avr_free_irq(avr_irq_t * irq, uint32_t count); - -// init 'count' IRQs, initializes their "irq" starting from 'base' and increment -void avr_init_irq(avr_irq_t * irq, uint32_t base, uint32_t count); -// 'raise' an IRQ. Ie call their 'hooks', and raise any chained IRQs, and set the new 'value' -void avr_raise_irq(avr_irq_t * irq, uint32_t value); -// this connects a "source" IRQ to a "destination" IRQ -void avr_connect_irq(avr_irq_t * src, avr_irq_t * dst); -// register a notification 'hook' for 'irq' -- 'param' is anything that your want passed back as argument -void avr_irq_register_notify(avr_irq_t * irq, avr_irq_notify_t notify, void * param); +//! allocates 'count' IRQs, initializes their "irq" starting from 'base' and increment +avr_irq_t * +avr_alloc_irq( + avr_irq_pool_t * pool, + uint32_t base, + uint32_t count, + const char ** names /* optional */); +void +avr_free_irq( + avr_irq_t * irq, + uint32_t count); + +//! init 'count' IRQs, initializes their "irq" starting from 'base' and increment +void +avr_init_irq( + avr_irq_pool_t * pool, + avr_irq_t * irq, + uint32_t base, + uint32_t count, + const char ** names /* optional */); +//! 'raise' an IRQ. Ie call their 'hooks', and raise any chained IRQs, and set the new 'value' +void +avr_raise_irq( + avr_irq_t * irq, + uint32_t value); +//! this connects a "source" IRQ to a "destination" IRQ +void +avr_connect_irq( + avr_irq_t * src, + avr_irq_t * dst); +//! register a notification 'hook' for 'irq' -- 'param' is anything that your want passed back as argument +void +avr_irq_register_notify( + avr_irq_t * irq, + avr_irq_notify_t notify, + void * param); #ifdef __cplusplus }; -- 2.39.5