2
0

irq.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #include "picorv32.h"
  2. #include "fw.h"
  3. static irq_handler_t irq_handlers[IRQ_VECTORS];
  4. /* Main IRQ dispatch; the .init.irq section puts it at the IRQ vector */
  5. void __attribute__((interrupt,section(".init.irq"))) _irq(void)
  6. {
  7. unsigned int mask = p_getq(1);
  8. unsigned int nirq = 0;
  9. while (mask) {
  10. bool handled;
  11. irq_handler_t handler;
  12. if (!(uint16_t)mask) {
  13. mask >>= 16;
  14. nirq += 16;
  15. }
  16. if (!(uint8_t)mask) {
  17. mask >>= 8;
  18. nirq += 8;
  19. }
  20. if (!(mask & 15)) {
  21. mask >>= 4;
  22. nirq += 4;
  23. }
  24. if (!(mask & 3)) {
  25. mask >>= 2;
  26. nirq += 2;
  27. }
  28. if (!(mask & 1)) {
  29. mask >>= 1;
  30. nirq += 1;
  31. }
  32. /* Now mask[0] is known to be 1 and nirq contains an active irq */
  33. handled = false;
  34. handler = irq_handlers[nirq];
  35. if (likely(handler))
  36. handled = handler(nirq);
  37. if (unlikely(!handled)) {
  38. uint32_t thisirq = (uint32_t)1 << nirq;
  39. /* Mask this IRQ but don't touch others */
  40. p_maskirq(thisirq, ~thisirq);
  41. }
  42. }
  43. }
  44. irq_handler_t register_irq(unsigned int vector, irq_handler_t handler)
  45. {
  46. irq_handler_t old_handler;
  47. if (vector >= IRQ_VECTORS)
  48. return NULL; /* Invalid vector */
  49. old_handler = irq_handlers[vector];
  50. irq_handlers[vector] = handler;
  51. return old_handler;
  52. }