xcall.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright (c) 2014-2018 Richard Braun.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. *
  18. * Cross-processor function calls.
  19. *
  20. * This module provides the ability to run functions, called cross-calls,
  21. * on specific processors.
  22. */
  23. #ifndef KERN_XCALL_H
  24. #define KERN_XCALL_H
  25. #include <stdint.h>
  26. #include <kern/init.h>
  27. #include <kern/spinlock.h>
  28. #include <kern/work.h>
  29. // Type for cross-call functions.
  30. typedef void (*xcall_fn_t) (void *arg);
  31. // Asynchronous cross-call data structure.
  32. struct xcall_async
  33. {
  34. struct work work;
  35. xcall_fn_t fn;
  36. void *arg;
  37. uint32_t cpu;
  38. struct spinlock lock;
  39. struct thread *waiter;
  40. bool done;
  41. };
  42. /*
  43. * Run the given cross-call function on a specific processor.
  44. *
  45. * The operation is completely synchronous, returning only when the function
  46. * has finished running on the target processor. Release-acquire ordering is
  47. * enforced both before and after the function runs on the target processor,
  48. * so that side effects produced by the caller are visible to the function,
  49. * and vice-versa on return.
  50. *
  51. * The callback function runs in interrupt context. Interrupts must be enabled
  52. * when calling this function.
  53. */
  54. void xcall_call (xcall_fn_t fn, void *arg, uint32_t cpu);
  55. // Initialize an async-xcall.
  56. void xcall_async_init (struct xcall_async *async,
  57. xcall_fn_t fn, void *arg, uint32_t cpu);
  58. // Same as xcall_call, only it's performed asynchronously.
  59. void xcall_async_call (struct xcall_async *async);
  60. // Wait for an async xcall to finish.
  61. void xcall_async_wait (struct xcall_async *async);
  62. int xcall_async_timedwait (struct xcall_async *async,
  63. uint64_t ticks, bool absolute);
  64. static inline bool
  65. xcall_async_done (const struct xcall_async *async)
  66. {
  67. return (async->done);
  68. }
  69. /*
  70. * Handle a cross-call interrupt from a remote processor.
  71. *
  72. * Called from interrupt context.
  73. */
  74. void xcall_intr (void);
  75. /*
  76. * This init operation provides :
  77. * - cross-calls are usable
  78. * - module fully initialized
  79. */
  80. INIT_OP_DECLARE (xcall_setup);
  81. #endif