source: rtems/bsps/shared/irq/irq-server.c @ 9b7c456

5
Last change on this file since 9b7c456 was 9b7c456, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 5, 2018 at 4:40:02 AM

bsps: Move generic IRQ support to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 18.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_interrupt
5 *
6 * @brief Generic BSP interrupt server implementation.
7 */
8
9/*
10 * Copyright (c) 2009, 2017 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <stdlib.h>
24
25#include <rtems.h>
26#include <rtems/chain.h>
27#include <rtems/score/assert.h>
28
29#include <bsp/irq-generic.h>
30
31#define BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR (BSP_INTERRUPT_VECTOR_MAX + 1)
32
33typedef struct {
34  RTEMS_INTERRUPT_LOCK_MEMBER(lock);
35  rtems_chain_control entries;
36  rtems_id server;
37  unsigned errors;
38} bsp_interrupt_server_context;
39
40#if defined(RTEMS_SMP)
41static bsp_interrupt_server_context *bsp_interrupt_server_instances;
42#else
43static bsp_interrupt_server_context bsp_interrupt_server_instance;
44#endif
45
46static bsp_interrupt_server_context *bsp_interrupt_server_get_context(
47  uint32_t server_index,
48  rtems_status_code *sc
49)
50{
51#if defined(RTEMS_SMP)
52  if (bsp_interrupt_server_instances == NULL) {
53    *sc = RTEMS_INCORRECT_STATE;
54    return NULL;
55  }
56#else
57  if (bsp_interrupt_server_instance.server == RTEMS_ID_NONE) {
58    *sc = RTEMS_INCORRECT_STATE;
59    return NULL;
60  }
61#endif
62
63  if (server_index >= rtems_get_processor_count()) {
64    *sc = RTEMS_INVALID_ID;
65    return NULL;
66  }
67
68  *sc = RTEMS_SUCCESSFUL;
69#if defined(RTEMS_SMP)
70  return &bsp_interrupt_server_instances[server_index];
71#else
72  return &bsp_interrupt_server_instance;
73#endif
74}
75
76static void bsp_interrupt_server_trigger(void *arg)
77{
78  rtems_interrupt_lock_context lock_context;
79  rtems_interrupt_server_entry *e = arg;
80  bsp_interrupt_server_context *s = e->server;
81
82  if (bsp_interrupt_is_valid_vector(e->vector)) {
83    bsp_interrupt_vector_disable(e->vector);
84  }
85
86  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
87
88  if (rtems_chain_is_node_off_chain(&e->node)) {
89    rtems_chain_append_unprotected(&s->entries, &e->node);
90  } else {
91    ++s->errors;
92  }
93
94  rtems_interrupt_lock_release(&s->lock, &lock_context);
95
96  rtems_event_system_send(s->server, RTEMS_EVENT_SYSTEM_SERVER);
97}
98
99typedef struct {
100  rtems_interrupt_server_entry *entry;
101  rtems_option *options;
102} bsp_interrupt_server_iterate_entry;
103
104static void bsp_interrupt_server_per_handler_routine(
105  void *iterate_arg,
106  const char *info,
107  rtems_option options,
108  rtems_interrupt_handler handler,
109  void *handler_arg
110)
111{
112  if (handler == bsp_interrupt_server_trigger) {
113    bsp_interrupt_server_iterate_entry *ie = iterate_arg;
114
115    ie->entry = handler_arg;
116    *ie->options = options;
117  }
118}
119
120static rtems_interrupt_server_entry *bsp_interrupt_server_query_entry(
121  rtems_vector_number vector,
122  rtems_option *trigger_options
123)
124{
125  bsp_interrupt_server_iterate_entry ie = {
126    .entry = NULL,
127    .options = trigger_options
128  };
129
130  rtems_interrupt_handler_iterate(
131    vector,
132    bsp_interrupt_server_per_handler_routine,
133    &ie
134  );
135
136  return ie.entry;
137}
138
139typedef struct {
140  bsp_interrupt_server_context *server;
141  rtems_vector_number vector;
142  rtems_option options;
143  rtems_interrupt_handler handler;
144  void *arg;
145  rtems_id task;
146  rtems_status_code sc;
147} bsp_interrupt_server_helper_data;
148
149static void bsp_interrupt_server_install_helper(void *arg)
150{
151  bsp_interrupt_server_helper_data *hd = arg;
152  rtems_status_code sc;
153  rtems_interrupt_server_entry *e;
154  rtems_interrupt_server_action *a;
155  rtems_option trigger_options;
156
157  a = calloc(1, sizeof(*a));
158  if (a == NULL) {
159    hd->sc = RTEMS_NO_MEMORY;
160    rtems_event_transient_send(hd->task);
161    return;
162  }
163
164  a->handler = hd->handler;
165  a->arg = hd->arg;
166
167  bsp_interrupt_lock();
168
169  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
170  if (e == NULL) {
171    e = calloc(1, sizeof(*e));
172    if (e != NULL) {
173      e->server = hd->server;
174      e->vector = hd->vector;
175      e->actions = a;
176
177      sc = rtems_interrupt_handler_install(
178        hd->vector,
179        "IRQS",
180        hd->options & RTEMS_INTERRUPT_UNIQUE,
181        bsp_interrupt_server_trigger,
182        e
183      );
184      if (sc != RTEMS_SUCCESSFUL) {
185        free(e);
186      }
187    } else {
188      sc = RTEMS_NO_MEMORY;
189    }
190#if defined(RTEMS_SMP)
191  } else if (e->server != hd->server) {
192    sc = RTEMS_RESOURCE_IN_USE;
193#endif
194  } else if (
195    RTEMS_INTERRUPT_IS_UNIQUE(hd->options)
196      || RTEMS_INTERRUPT_IS_UNIQUE(trigger_options)
197  ) {
198    sc = RTEMS_RESOURCE_IN_USE;
199  } else {
200    rtems_interrupt_server_action **link = &e->actions;
201    rtems_interrupt_server_action *c;
202
203    sc = RTEMS_SUCCESSFUL;
204
205    while ((c = *link) != NULL) {
206      if (c->handler == hd->handler && c->arg == hd->arg) {
207        sc = RTEMS_TOO_MANY;
208        break;
209      }
210
211      link = &c->next;
212    }
213
214    if (sc == RTEMS_SUCCESSFUL) {
215      *link = a;
216    }
217  }
218
219  bsp_interrupt_unlock();
220
221  if (sc != RTEMS_SUCCESSFUL) {
222    free(a);
223  }
224
225  hd->sc = sc;
226  rtems_event_transient_send(hd->task);
227}
228
229static void bsp_interrupt_server_remove_helper(void *arg)
230{
231  bsp_interrupt_server_helper_data *hd = arg;
232  rtems_status_code sc;
233  rtems_interrupt_server_entry *e;
234  rtems_option trigger_options;
235
236  bsp_interrupt_lock();
237
238  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
239  if (e != NULL) {
240    rtems_interrupt_server_action **link = &e->actions;
241    rtems_interrupt_server_action *c;
242
243    while ((c = *link) != NULL) {
244      if (c->handler == hd->handler && c->arg == hd->arg) {
245        break;
246      }
247
248      link = &c->next;
249    }
250
251    if (c != NULL) {
252      bool remove_last = e->actions->next == NULL;
253
254      if (remove_last) {
255        rtems_interrupt_handler_remove(
256          hd->vector,
257          bsp_interrupt_server_trigger,
258          e
259        );
260      }
261
262      *link = c->next;
263      free(c);
264
265      if (remove_last) {
266        free(e);
267      }
268
269      sc = RTEMS_SUCCESSFUL;
270    } else {
271      sc = RTEMS_UNSATISFIED;
272    }
273  } else {
274    sc = RTEMS_INVALID_ID;
275  }
276
277  bsp_interrupt_unlock();
278
279  hd->sc = sc;
280  rtems_event_transient_send(hd->task);
281}
282
283static rtems_status_code bsp_interrupt_server_call_helper(
284  bsp_interrupt_server_context *s,
285  rtems_vector_number vector,
286  rtems_option options,
287  rtems_interrupt_handler handler,
288  void *arg,
289  void (*helper)(void *)
290)
291{
292  bsp_interrupt_server_helper_data hd = {
293    .server = s,
294    .vector = vector,
295    .options = options,
296    .handler = handler,
297    .arg = arg,
298    .task = rtems_task_self()
299  };
300  rtems_interrupt_server_action a = {
301    .handler = helper,
302    .arg = &hd
303  };
304  rtems_interrupt_server_entry e = {
305    .server = s,
306    .vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
307    .actions = &a
308  };
309
310  bsp_interrupt_server_trigger(&e);
311  rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
312
313  return hd.sc;
314}
315
316static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(
317  bsp_interrupt_server_context *s
318)
319{
320  rtems_interrupt_lock_context lock_context;
321  rtems_interrupt_server_entry *e;
322
323  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
324
325  if (!rtems_chain_is_empty(&s->entries)) {
326    e = (rtems_interrupt_server_entry *)
327      rtems_chain_get_first_unprotected(&s->entries);
328    rtems_chain_set_off_chain(&e->node);
329  } else {
330    e = NULL;
331  }
332
333  rtems_interrupt_lock_release(&s->lock, &lock_context);
334
335  return e;
336}
337
338static void bsp_interrupt_server_task(rtems_task_argument arg)
339{
340  bsp_interrupt_server_context *s = (bsp_interrupt_server_context *) arg;
341
342  while (true) {
343    rtems_event_set events;
344    rtems_interrupt_server_entry *e;
345
346    rtems_event_system_receive(
347      RTEMS_EVENT_SYSTEM_SERVER,
348      RTEMS_EVENT_ALL | RTEMS_WAIT,
349      RTEMS_NO_TIMEOUT,
350      &events
351    );
352
353    while ((e = bsp_interrupt_server_get_entry(s)) != NULL) {
354      rtems_interrupt_server_action *action = e->actions;
355      rtems_vector_number vector = e->vector;
356
357      do {
358        rtems_interrupt_server_action *current = action;
359        action = action->next;
360        (*current->handler)(current->arg);
361      } while (action != NULL);
362
363      if (bsp_interrupt_is_valid_vector(vector)) {
364        bsp_interrupt_vector_enable(vector);
365      }
366    }
367  }
368}
369
370rtems_status_code rtems_interrupt_server_handler_install(
371  uint32_t server_index,
372  rtems_vector_number vector,
373  const char *info,
374  rtems_option options,
375  rtems_interrupt_handler handler,
376  void *arg
377)
378{
379  rtems_status_code sc;
380  bsp_interrupt_server_context *s;
381
382  s = bsp_interrupt_server_get_context(server_index, &sc);
383  if (s == NULL) {
384    return sc;
385  }
386
387  return bsp_interrupt_server_call_helper(
388    s,
389    vector,
390    options,
391    handler,
392    arg,
393    bsp_interrupt_server_install_helper
394  );
395}
396
397rtems_status_code rtems_interrupt_server_handler_remove(
398  uint32_t server_index,
399  rtems_vector_number vector,
400  rtems_interrupt_handler handler,
401  void *arg
402)
403{
404  rtems_status_code sc;
405  bsp_interrupt_server_context *s;
406
407  s = bsp_interrupt_server_get_context(server_index, &sc);
408  if (s == NULL) {
409    return sc;
410  }
411
412  return bsp_interrupt_server_call_helper(
413    s,
414    vector,
415    0,
416    handler,
417    arg,
418    bsp_interrupt_server_remove_helper
419  );
420}
421
422typedef struct {
423  rtems_interrupt_per_handler_routine routine;
424  void *arg;
425} bsp_interrupt_server_handler_iterate_helper_data;
426
427static void bsp_interrupt_server_handler_iterate_helper(void *arg)
428{
429  bsp_interrupt_server_helper_data *hd = arg;
430  bsp_interrupt_server_handler_iterate_helper_data *hihd = hd->arg;
431  rtems_status_code sc;
432  rtems_interrupt_server_entry *e;
433  rtems_option trigger_options;
434
435  bsp_interrupt_lock();
436
437  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
438  if (e != NULL) {
439    rtems_interrupt_server_action **link = &e->actions;
440    rtems_interrupt_server_action *c;
441
442    while ((c = *link) != NULL) {
443      (*hihd->routine)(hihd->arg, NULL, trigger_options, c->handler, c->arg);
444      link = &c->next;
445    }
446
447    sc = RTEMS_SUCCESSFUL;
448  } else {
449    sc = RTEMS_UNSATISFIED;
450  }
451
452  bsp_interrupt_unlock();
453
454  hd->sc = sc;
455  rtems_event_transient_send(hd->task);
456}
457
458rtems_status_code rtems_interrupt_server_handler_iterate(
459  uint32_t server_index,
460  rtems_vector_number vector,
461  rtems_interrupt_per_handler_routine routine,
462  void *arg
463)
464{
465  rtems_status_code sc;
466  bsp_interrupt_server_handler_iterate_helper_data hihd;
467  bsp_interrupt_server_context *s;
468
469  s = bsp_interrupt_server_get_context(server_index, &sc);
470  if (s == NULL) {
471    return sc;
472  }
473
474  if (!bsp_interrupt_is_valid_vector(vector)) {
475    return RTEMS_INVALID_ID;
476  }
477
478  hihd.routine = routine;
479  hihd.arg = arg;
480  return bsp_interrupt_server_call_helper(
481    s,
482    vector,
483    0,
484    NULL,
485    &hihd,
486    bsp_interrupt_server_handler_iterate_helper
487  );
488}
489
490rtems_status_code rtems_interrupt_server_initialize(
491  rtems_task_priority priority,
492  size_t stack_size,
493  rtems_mode modes,
494  rtems_attribute attributes,
495  uint32_t *server_count
496)
497{
498  uint32_t cpu_index;
499  uint32_t cpu_count;
500  uint32_t dummy;
501  bsp_interrupt_server_context *instances;
502
503  if (server_count == NULL) {
504    server_count = &dummy;
505  }
506
507  cpu_count = rtems_get_processor_count();
508
509#if defined(RTEMS_SMP)
510  instances = calloc(cpu_count, sizeof(*instances));
511  if (instances == NULL) {
512    return RTEMS_NO_MEMORY;
513  }
514#else
515  instances = &bsp_interrupt_server_instance;
516#endif
517
518  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
519    bsp_interrupt_server_context *s = &instances[cpu_index];
520    rtems_status_code sc;
521#if defined(RTEMS_SMP)
522    rtems_id scheduler;
523    cpu_set_t cpu;
524#endif
525
526    rtems_interrupt_lock_initialize(&s->lock, "Interrupt Server");
527    rtems_chain_initialize_empty(&s->entries);
528
529    sc = rtems_task_create(
530      rtems_build_name('I', 'R', 'Q', 'S'),
531      priority,
532      stack_size,
533      modes,
534      attributes,
535      &s->server
536    );
537    if (sc != RTEMS_SUCCESSFUL) {
538      *server_count = cpu_index;
539
540#if defined(RTEMS_SMP)
541      if (cpu_index > 0) {
542        return RTEMS_SUCCESSFUL;
543      }
544
545      free(instances);
546#endif
547
548      return RTEMS_TOO_MANY;
549    }
550
551#if defined(RTEMS_SMP)
552    sc = rtems_scheduler_ident_by_processor(cpu_index, &scheduler);
553    _Assert(sc == RTEMS_SUCCESSFUL);
554
555    sc = rtems_task_set_scheduler(s->server, scheduler, priority);
556    _Assert(sc == RTEMS_SUCCESSFUL);
557
558    CPU_ZERO(&cpu);
559    CPU_SET(cpu_index, &cpu);
560    sc = rtems_task_set_affinity(s->server, sizeof(cpu), &cpu);
561    _Assert(sc == RTEMS_SUCCESSFUL);
562#endif
563
564    sc = rtems_task_start(
565      s->server,
566      bsp_interrupt_server_task,
567      (rtems_task_argument) s
568    );
569    _Assert(sc == RTEMS_SUCCESSFUL);
570  }
571
572#if defined(RTEMS_SMP)
573  bsp_interrupt_server_instances = instances;
574#endif
575  *server_count = cpu_index;
576
577  return RTEMS_SUCCESSFUL;
578}
579
580static void bsp_interrupt_server_entry_initialize(
581  rtems_interrupt_server_entry *entry,
582  bsp_interrupt_server_context *s
583)
584{
585  rtems_chain_set_off_chain(&entry->node);
586  entry->server = s;
587  entry->vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR;
588  entry->actions = NULL;
589}
590
591static void bsp_interrupt_server_action_prepend(
592  rtems_interrupt_server_entry  *entry,
593  rtems_interrupt_server_action *action,
594  rtems_interrupt_handler        handler,
595  void                          *arg
596)
597{
598  action->handler = handler;
599  action->arg = arg;
600  action->next = entry->actions;
601  entry->actions = action;
602}
603
604rtems_status_code rtems_interrupt_server_entry_initialize(
605  uint32_t                      server_index,
606  rtems_interrupt_server_entry *entry
607)
608{
609  rtems_status_code sc;
610  bsp_interrupt_server_context *s;
611
612  s = bsp_interrupt_server_get_context(server_index, &sc);
613  if (s == NULL) {
614    return sc;
615  }
616
617  bsp_interrupt_server_entry_initialize(entry, s);
618  return RTEMS_SUCCESSFUL;
619}
620
621void rtems_interrupt_server_action_prepend(
622  rtems_interrupt_server_entry  *entry,
623  rtems_interrupt_server_action *action,
624  rtems_interrupt_handler        handler,
625  void                          *arg
626)
627{
628  bsp_interrupt_server_action_prepend(entry, action, handler, arg);
629}
630
631void rtems_interrupt_server_entry_submit(
632  rtems_interrupt_server_entry *entry
633)
634{
635  bsp_interrupt_server_trigger(entry);
636}
637
638static void bsp_interrupt_server_entry_synchronize_helper(void *arg)
639{
640  bsp_interrupt_server_helper_data *hd = arg;
641
642  rtems_event_transient_send(hd->task);
643}
644
645void rtems_interrupt_server_entry_destroy(
646  rtems_interrupt_server_entry *entry
647)
648{
649  bsp_interrupt_server_context *s;
650  rtems_interrupt_lock_context lock_context;
651
652  s = entry->server;
653  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
654
655  if (!rtems_chain_is_node_off_chain(&entry->node)) {
656    rtems_chain_extract_unprotected(&entry->node);
657    rtems_chain_set_off_chain(&entry->node);
658  }
659
660  rtems_interrupt_lock_release(&s->lock, &lock_context);
661
662  bsp_interrupt_server_call_helper(
663    s,
664    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
665    0,
666    NULL,
667    NULL,
668    bsp_interrupt_server_entry_synchronize_helper
669  );
670}
671
672rtems_status_code rtems_interrupt_server_request_initialize(
673  uint32_t                        server_index,
674  rtems_interrupt_server_request *request,
675  rtems_interrupt_handler         handler,
676  void                           *arg
677)
678{
679  rtems_status_code sc;
680  bsp_interrupt_server_context *s;
681
682  s = bsp_interrupt_server_get_context(server_index, &sc);
683  if (s == NULL) {
684    return sc;
685  }
686
687  bsp_interrupt_server_entry_initialize(&request->entry, s);
688  bsp_interrupt_server_action_prepend(
689    &request->entry,
690    &request->action,
691    handler,
692    arg
693  );
694  return RTEMS_SUCCESSFUL;
695}
696
697static void bsp_interrupt_server_handler_move_helper(void *arg)
698{
699  bsp_interrupt_server_helper_data *hd = arg;
700  bsp_interrupt_server_handler_iterate_helper_data *hihd = hd->arg;
701  rtems_interrupt_server_entry *e;
702  rtems_option trigger_options;
703
704  bsp_interrupt_lock();
705
706  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
707  if (e != NULL) {
708    rtems_interrupt_lock_context lock_context;
709    bsp_interrupt_server_context *src = e->server;
710    bsp_interrupt_server_context *dst = hihd->arg;
711    bool pending;
712
713    /* The source server is only used in SMP configurations for the lock */
714    (void) src;
715
716    rtems_interrupt_lock_acquire(&src->lock, &lock_context);
717
718    pending = !rtems_chain_is_node_off_chain(&e->node);
719    if (pending) {
720      rtems_chain_extract_unprotected(&e->node);
721      rtems_chain_set_off_chain(&e->node);
722    }
723
724    rtems_interrupt_lock_release(&src->lock, &lock_context);
725
726    e->server = dst;
727
728    if (pending) {
729      bsp_interrupt_server_trigger(e);
730    }
731  }
732
733  bsp_interrupt_unlock();
734
735  rtems_event_transient_send(hd->task);
736}
737
738rtems_status_code rtems_interrupt_server_move(
739  uint32_t source_server_index,
740  rtems_vector_number vector,
741  uint32_t destination_server_index
742)
743{
744  rtems_status_code sc;
745  bsp_interrupt_server_context *src;
746  bsp_interrupt_server_context *dst;
747  bsp_interrupt_server_handler_iterate_helper_data hihd;
748
749  src = bsp_interrupt_server_get_context(source_server_index, &sc);
750  if (src == NULL) {
751    return sc;
752  }
753
754  dst = bsp_interrupt_server_get_context(destination_server_index, &sc);
755  if (dst == NULL) {
756    return sc;
757  }
758
759  if (!bsp_interrupt_is_valid_vector(vector)) {
760    return RTEMS_INVALID_ID;
761  }
762
763  hihd.arg = dst;
764  bsp_interrupt_server_call_helper(
765    src,
766    vector,
767    0,
768    NULL,
769    &hihd,
770    bsp_interrupt_server_handler_move_helper
771  );
772  return RTEMS_SUCCESSFUL;
773}
774
775static void bsp_interrupt_server_entry_suspend_helper(void *arg)
776{
777  bsp_interrupt_server_helper_data *hd = arg;
778  rtems_event_set events;
779
780  rtems_event_transient_send(hd->task);
781  rtems_event_system_receive(
782    RTEMS_EVENT_SYSTEM_SERVER_RESUME,
783    RTEMS_WAIT,
784    RTEMS_NO_TIMEOUT,
785    &events
786  );
787}
788
789rtems_status_code rtems_interrupt_server_suspend(uint32_t server_index)
790{
791  rtems_status_code sc;
792  bsp_interrupt_server_context *s;
793
794  s = bsp_interrupt_server_get_context(server_index, &sc);
795  if (s == NULL) {
796    return sc;
797  }
798
799  bsp_interrupt_server_call_helper(
800    s,
801    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
802    0,
803    NULL,
804    NULL,
805    bsp_interrupt_server_entry_suspend_helper
806  );
807  return RTEMS_SUCCESSFUL;
808}
809
810rtems_status_code rtems_interrupt_server_resume(uint32_t server_index)
811{
812  rtems_status_code sc;
813  bsp_interrupt_server_context *s;
814
815  s = bsp_interrupt_server_get_context(server_index, &sc);
816  if (s == NULL) {
817    return sc;
818  }
819
820  rtems_event_system_send(s->server, RTEMS_EVENT_SYSTEM_SERVER_RESUME);
821  bsp_interrupt_server_call_helper(
822    s,
823    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
824    0,
825    NULL,
826    NULL,
827    bsp_interrupt_server_entry_synchronize_helper
828  );
829  return RTEMS_SUCCESSFUL;
830}
831
832rtems_status_code rtems_interrupt_server_set_affinity(
833  uint32_t            server_index,
834  size_t              affinity_size,
835  const cpu_set_t    *affinity,
836  rtems_task_priority priority
837)
838{
839  rtems_status_code sc;
840  bsp_interrupt_server_context *s;
841  rtems_id scheduler;
842
843  s = bsp_interrupt_server_get_context(server_index, &sc);
844  if (s == NULL) {
845    return sc;
846  }
847
848  sc = rtems_scheduler_ident_by_processor_set(
849    affinity_size,
850    affinity,
851    &scheduler
852  );
853  if (sc != RTEMS_SUCCESSFUL) {
854    return sc;
855  }
856
857  sc = rtems_task_set_scheduler(s->server, scheduler, priority);
858  if (sc != RTEMS_SUCCESSFUL) {
859    return sc;
860  }
861
862  return rtems_task_set_affinity(s->server, affinity_size, affinity);
863}
Note: See TracBrowser for help on using the repository browser.