source: rtems/bsps/shared/irq/irq-server.c @ 33ed412

5
Last change on this file since 33ed412 was 33ed412, checked in by Sebastian Huber <sebastian.huber@…>, on 09/20/19 at 07:16:17

rtems: Add rtems_interrupt_server_entry_move()

The use case for this function is the libbsd. In FreeBSD, the interrupt
setup and binding to a processor is done in two steps. Message
based interrupts like PCIe MSI and MSI-X interrupts can be implemented
through interrupt server entries. They are setup at the default
interrupt server and may optionally move to an interrupt server bound to
a specific processor.

  • Property mode set to 100644
File size: 19.4 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, 2019 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_scheduler_get_processor_maximum()) {
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_scheduler_get_processor_maximum();
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    if (sc != RTEMS_SUCCESSFUL) {
554      /* Do not start an interrupt server on a processor without a scheduler */
555      continue;
556    }
557
558    sc = rtems_task_set_scheduler(s->server, scheduler, priority);
559    _Assert(sc == RTEMS_SUCCESSFUL);
560
561    /* Set the task to processor affinity on a best-effort basis */
562    CPU_ZERO(&cpu);
563    CPU_SET(cpu_index, &cpu);
564    (void) rtems_task_set_affinity(s->server, sizeof(cpu), &cpu);
565#endif
566
567    sc = rtems_task_start(
568      s->server,
569      bsp_interrupt_server_task,
570      (rtems_task_argument) s
571    );
572    _Assert(sc == RTEMS_SUCCESSFUL);
573  }
574
575#if defined(RTEMS_SMP)
576  bsp_interrupt_server_instances = instances;
577#endif
578  *server_count = cpu_index;
579
580  return RTEMS_SUCCESSFUL;
581}
582
583static void bsp_interrupt_server_entry_initialize(
584  rtems_interrupt_server_entry *entry,
585  bsp_interrupt_server_context *s
586)
587{
588  rtems_chain_set_off_chain(&entry->node);
589  entry->server = s;
590  entry->vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR;
591  entry->actions = NULL;
592}
593
594static void bsp_interrupt_server_action_prepend(
595  rtems_interrupt_server_entry  *entry,
596  rtems_interrupt_server_action *action,
597  rtems_interrupt_handler        handler,
598  void                          *arg
599)
600{
601  action->handler = handler;
602  action->arg = arg;
603  action->next = entry->actions;
604  entry->actions = action;
605}
606
607rtems_status_code rtems_interrupt_server_entry_initialize(
608  uint32_t                      server_index,
609  rtems_interrupt_server_entry *entry
610)
611{
612  rtems_status_code sc;
613  bsp_interrupt_server_context *s;
614
615  s = bsp_interrupt_server_get_context(server_index, &sc);
616  if (s == NULL) {
617    return sc;
618  }
619
620  bsp_interrupt_server_entry_initialize(entry, s);
621  return RTEMS_SUCCESSFUL;
622}
623
624void rtems_interrupt_server_action_prepend(
625  rtems_interrupt_server_entry  *entry,
626  rtems_interrupt_server_action *action,
627  rtems_interrupt_handler        handler,
628  void                          *arg
629)
630{
631  bsp_interrupt_server_action_prepend(entry, action, handler, arg);
632}
633
634void rtems_interrupt_server_entry_submit(
635  rtems_interrupt_server_entry *entry
636)
637{
638  bsp_interrupt_server_trigger(entry);
639}
640
641rtems_status_code rtems_interrupt_server_entry_move(
642  rtems_interrupt_server_entry *entry,
643  uint32_t                      destination_server_index
644)
645{
646  rtems_status_code sc;
647  bsp_interrupt_server_context *s;
648
649  s = bsp_interrupt_server_get_context(destination_server_index, &sc);
650  if (s == NULL) {
651    return sc;
652  }
653
654  entry->server = s;
655  return RTEMS_SUCCESSFUL;
656}
657
658static void bsp_interrupt_server_entry_synchronize_helper(void *arg)
659{
660  bsp_interrupt_server_helper_data *hd = arg;
661
662  rtems_event_transient_send(hd->task);
663}
664
665void rtems_interrupt_server_entry_destroy(
666  rtems_interrupt_server_entry *entry
667)
668{
669  bsp_interrupt_server_context *s;
670  rtems_interrupt_lock_context lock_context;
671
672  s = entry->server;
673  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
674
675  if (!rtems_chain_is_node_off_chain(&entry->node)) {
676    rtems_chain_extract_unprotected(&entry->node);
677    rtems_chain_set_off_chain(&entry->node);
678  }
679
680  rtems_interrupt_lock_release(&s->lock, &lock_context);
681
682  bsp_interrupt_server_call_helper(
683    s,
684    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
685    0,
686    NULL,
687    NULL,
688    bsp_interrupt_server_entry_synchronize_helper
689  );
690}
691
692rtems_status_code rtems_interrupt_server_request_initialize(
693  uint32_t                        server_index,
694  rtems_interrupt_server_request *request,
695  rtems_interrupt_handler         handler,
696  void                           *arg
697)
698{
699  rtems_status_code sc;
700  bsp_interrupt_server_context *s;
701
702  s = bsp_interrupt_server_get_context(server_index, &sc);
703  if (s == NULL) {
704    return sc;
705  }
706
707  bsp_interrupt_server_entry_initialize(&request->entry, s);
708  bsp_interrupt_server_action_prepend(
709    &request->entry,
710    &request->action,
711    handler,
712    arg
713  );
714  return RTEMS_SUCCESSFUL;
715}
716
717static void bsp_interrupt_server_handler_move_helper(void *arg)
718{
719  bsp_interrupt_server_helper_data *hd = arg;
720  bsp_interrupt_server_handler_iterate_helper_data *hihd = hd->arg;
721  rtems_interrupt_server_entry *e;
722  rtems_option trigger_options;
723
724  bsp_interrupt_lock();
725
726  e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
727  if (e != NULL) {
728    rtems_interrupt_lock_context lock_context;
729    bsp_interrupt_server_context *src = e->server;
730    bsp_interrupt_server_context *dst = hihd->arg;
731    bool pending;
732
733    /* The source server is only used in SMP configurations for the lock */
734    (void) src;
735
736    rtems_interrupt_lock_acquire(&src->lock, &lock_context);
737
738    pending = !rtems_chain_is_node_off_chain(&e->node);
739    if (pending) {
740      rtems_chain_extract_unprotected(&e->node);
741      rtems_chain_set_off_chain(&e->node);
742    }
743
744    rtems_interrupt_lock_release(&src->lock, &lock_context);
745
746    e->server = dst;
747
748    if (pending) {
749      bsp_interrupt_server_trigger(e);
750    }
751  }
752
753  bsp_interrupt_unlock();
754
755  rtems_event_transient_send(hd->task);
756}
757
758rtems_status_code rtems_interrupt_server_move(
759  uint32_t source_server_index,
760  rtems_vector_number vector,
761  uint32_t destination_server_index
762)
763{
764  rtems_status_code sc;
765  bsp_interrupt_server_context *src;
766  bsp_interrupt_server_context *dst;
767  bsp_interrupt_server_handler_iterate_helper_data hihd;
768
769  src = bsp_interrupt_server_get_context(source_server_index, &sc);
770  if (src == NULL) {
771    return sc;
772  }
773
774  dst = bsp_interrupt_server_get_context(destination_server_index, &sc);
775  if (dst == NULL) {
776    return sc;
777  }
778
779  if (!bsp_interrupt_is_valid_vector(vector)) {
780    return RTEMS_INVALID_ID;
781  }
782
783  hihd.arg = dst;
784  bsp_interrupt_server_call_helper(
785    src,
786    vector,
787    0,
788    NULL,
789    &hihd,
790    bsp_interrupt_server_handler_move_helper
791  );
792  return RTEMS_SUCCESSFUL;
793}
794
795static void bsp_interrupt_server_entry_suspend_helper(void *arg)
796{
797  bsp_interrupt_server_helper_data *hd = arg;
798  rtems_event_set events;
799
800  rtems_event_transient_send(hd->task);
801  rtems_event_system_receive(
802    RTEMS_EVENT_SYSTEM_SERVER_RESUME,
803    RTEMS_WAIT,
804    RTEMS_NO_TIMEOUT,
805    &events
806  );
807}
808
809rtems_status_code rtems_interrupt_server_suspend(uint32_t server_index)
810{
811  rtems_status_code sc;
812  bsp_interrupt_server_context *s;
813
814  s = bsp_interrupt_server_get_context(server_index, &sc);
815  if (s == NULL) {
816    return sc;
817  }
818
819  bsp_interrupt_server_call_helper(
820    s,
821    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
822    0,
823    NULL,
824    NULL,
825    bsp_interrupt_server_entry_suspend_helper
826  );
827  return RTEMS_SUCCESSFUL;
828}
829
830rtems_status_code rtems_interrupt_server_resume(uint32_t server_index)
831{
832  rtems_status_code sc;
833  bsp_interrupt_server_context *s;
834
835  s = bsp_interrupt_server_get_context(server_index, &sc);
836  if (s == NULL) {
837    return sc;
838  }
839
840  rtems_event_system_send(s->server, RTEMS_EVENT_SYSTEM_SERVER_RESUME);
841  bsp_interrupt_server_call_helper(
842    s,
843    BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
844    0,
845    NULL,
846    NULL,
847    bsp_interrupt_server_entry_synchronize_helper
848  );
849  return RTEMS_SUCCESSFUL;
850}
851
852rtems_status_code rtems_interrupt_server_set_affinity(
853  uint32_t            server_index,
854  size_t              affinity_size,
855  const cpu_set_t    *affinity,
856  rtems_task_priority priority
857)
858{
859  rtems_status_code sc;
860  bsp_interrupt_server_context *s;
861  rtems_id scheduler;
862
863  s = bsp_interrupt_server_get_context(server_index, &sc);
864  if (s == NULL) {
865    return sc;
866  }
867
868  sc = rtems_scheduler_ident_by_processor_set(
869    affinity_size,
870    affinity,
871    &scheduler
872  );
873  if (sc != RTEMS_SUCCESSFUL) {
874    return sc;
875  }
876
877  sc = rtems_task_set_scheduler(s->server, scheduler, priority);
878  if (sc != RTEMS_SUCCESSFUL) {
879    return sc;
880  }
881
882  return rtems_task_set_affinity(s->server, affinity_size, affinity);
883}
Note: See TracBrowser for help on using the repository browser.