PowerPC exceptions and interrupts
Sebastian Huber
Sebastian.Huber at embedded-brains.de
Wed May 21 07:49:02 UTC 2008
Pavel Pisa wrote:
> On Tuesday 20 May 2008 09:22, Sebastian Huber wrote:
>
> [...]
>
>> static rtems_status_code rtems_interrupt_handler_install(
>> rtems_vector_number vector,
>> rtems_interrupt_handler handler,
>> void *arg
>> )
>>
>
> I think personally, that additional function
> rtems_interrupt_handler_unique_install()
> for unique handler install is not good idea.
> I would prefer to add some mode/flags field into
> regular rtems_interrupt_handler_install() function.
> You implementation uses this approach anyway.
> I would suggest to use masks provided by defines
> for these flags. You need sometimes specific modifications/
> modes for interrupts, not only RTEMS_IRQ_SHARE_ALLOWED.
> The Linux generic IRQ support converged to allow specify
> if IRQ is triggered on rising, falling edge or level directly
> in request_irq() function for GPIO IRQ sources for example.
>
>
Ok, good idea.
> The Linux adds ability to provide some user recognizable name
> for handler as well. This is not mandatory for RTEMS, but
> it could be of great help, if you need to check what is
> registered in the system and to display IRQ counters.
>
>
Hm, nice feature but this requires memory.
> So my proposal is
>
> static rtems_status_code rtems_interrupt_handler_install(
> rtems_vector_number vector,
> rtems_interrupt_handler handler,
> rtems_interrupt_flags flags,
> char *informative_name,
> void *arg
> )
>
>
>> static rtems_status_code rtems_interrupt_handler_remove(
>> rtems_vector_number vector,
>> rtems_interrupt_handler handler
>> )
>>
>
> As for the remove, I would again suggest to follow proven
> way, which is used in Linux. It has significant rationale.
> If you have shared interrupt source (consider PCI for example)
> and you can have multiple instances of same hardware (multiple
> ETHERNET cards for example) sharing same IRQ line, then
> you cannot control, which of multiple registration
> with same handler would be unregisterred. This could lead
> to fatal problems, that state structure for some card is
> destroyed, but handler for different one is unregisterred
> => handler with arg pointing to the free/reused memory
> would be used => disaster situation.
>
> On the other hand, if device context structure pointer
> ("arg") is used for selection which shared registration
> should be removed, than it finds correct registration instance.
>
> This means, that I would propose with Linux and other OS
> proven prototype
>
> static rtems_status_code rtems_interrupt_handler_remove(
> rtems_vector_number vector,
> void *arg
> )
>
> If you ensure safety even more, handler parameter could
> be left there as well. In such case, the functionality
> could be extended next way
>
> handler == NULL .. then only match for arg is checked
> arg == NULL .. then only match for handler is checked
> and all instances with this handler are removed
>
Ok, lets do it.
> (handler == NULL) && (arg == NULL) .. all registration
> for given vector are removed
>
>
I am a bit uneasy with this, because this allows you to remove alien
handlers (= private hander routines and arguments from other drivers).
> As for low level stuff and relation to the rtems_irq_connect_data,
> I have feeling, that your approach is upside down.
> It think, that rtems_irq_connect_data and IRQ controllers
> low level stuff should be base on which user friendly
> rtems_interrupt_handler_install() and
> rtems_status_code rtems_interrupt_handler_remove()
> should be based upon and not vice versa.
>
Yes. A rtems(!)_irq_connect_data is superfluous. Data structures are up
to the implementation.
> The IRQ controller support can gain from ability to have direct
> and fast aces to some (even architecture extendable) information
> context for each interrupt source
> typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
> typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
> typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
>
The is_enabled() function is not needed since you can check this in your
enable or disable function. We can merge the other two functions into
enable( enable, connect_data).
But do we really need this?
> [...]
>
>
>> typedef void(*rtems_interrupt_handler )(void *)
>>
>
> If we speak about generic support, then to allow
> correct sharing for all obscure controllers and
> even for edge triggered sources, then
> rtems_interrupt_handler
> prototype has to be modified to return information,
> if the even has been recognized by device driver or not
> typedef int rtems_interrupt_handled_state;
> typedef rtems_interrupt_handled_state (*rtems_interrupt_handler )(void *)
>
> The next algorithm is required to handle correctly shared edge
> triggered sources
>
> rtems_interrupt_handled_state again;
> rtems_interrupt_handled_state res;
> do {
> again = 0;
> for_each(vector->rtems_irq_connect_data_list, connect) {
> res=connect->hndl(connect->handle);
> if(res == RTEMS_INTERRUPT_HANDLED)
> again = 1;
> }
> } while(again);
>
> [...]
>
I am to inexperienced to comment this.
--
embedded brains GmbH
Sebastian Huber Obere Lagerstr. 30
D-82178 Puchheim Germany
Tel. : +49-89-18 90 80 79-6
Fax : +49-89-18 90 80 79-9
email: Sebastian.Huber at embedded-brains.de
PGP public key available on request
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the users
mailing list