interrupts.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2016-17 Microsemi Corporation.
  4. * Padmarao Begari, Microsemi Corporation <padmarao.begari@microsemi.com>
  5. *
  6. * Copyright (C) 2017 Andes Technology Corporation
  7. * Rick Chen, Andes Technology Corporation <rick@andestech.com>
  8. */
  9. #include <common.h>
  10. #include <hang.h>
  11. #include <irq_func.h>
  12. #include <asm/ptrace.h>
  13. #include <asm/system.h>
  14. #include <asm/encoding.h>
  15. static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
  16. {
  17. static const char * const exception_code[] = {
  18. "Instruction address misaligned",
  19. "Instruction access fault",
  20. "Illegal instruction",
  21. "Breakpoint",
  22. "Load address misaligned",
  23. "Load access fault",
  24. "Store/AMO address misaligned",
  25. "Store/AMO access fault",
  26. "Environment call from U-mode",
  27. "Environment call from S-mode",
  28. "Reserved",
  29. "Environment call from M-mode",
  30. "Instruction page fault",
  31. "Load page fault",
  32. "Reserved",
  33. "Store/AMO page fault",
  34. };
  35. if (code < ARRAY_SIZE(exception_code)) {
  36. printf("exception code: %ld , %s , epc %lx , ra %lx\n",
  37. code, exception_code[code], epc, regs->ra);
  38. } else {
  39. printf("reserved exception code: %ld , epc %lx , ra %lx\n",
  40. code, epc, regs->ra);
  41. }
  42. hang();
  43. }
  44. int interrupt_init(void)
  45. {
  46. return 0;
  47. }
  48. /*
  49. * enable interrupts
  50. */
  51. void enable_interrupts(void)
  52. {
  53. }
  54. /*
  55. * disable interrupts
  56. */
  57. int disable_interrupts(void)
  58. {
  59. return 0;
  60. }
  61. ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs)
  62. {
  63. ulong is_irq, irq;
  64. is_irq = (cause & MCAUSE_INT);
  65. irq = (cause & ~MCAUSE_INT);
  66. if (is_irq) {
  67. switch (irq) {
  68. case IRQ_M_EXT:
  69. case IRQ_S_EXT:
  70. external_interrupt(0); /* handle external interrupt */
  71. break;
  72. case IRQ_M_TIMER:
  73. case IRQ_S_TIMER:
  74. timer_interrupt(0); /* handle timer interrupt */
  75. break;
  76. default:
  77. _exit_trap(cause, epc, regs);
  78. break;
  79. };
  80. } else {
  81. _exit_trap(cause, epc, regs);
  82. }
  83. return epc;
  84. }
  85. /*
  86. *Entry Point for PLIC Interrupt Handler
  87. */
  88. __attribute__((weak)) void external_interrupt(struct pt_regs *regs)
  89. {
  90. }
  91. __attribute__((weak)) void timer_interrupt(struct pt_regs *regs)
  92. {
  93. }