aboutsummaryrefslogtreecommitdiff
path: root/include/isr_vector.h
blob: 3d4070afaa70f7942bd58bc978f3cb746b2c8a7d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#pragma once

#include <stdint.h>

/** Reference to the global ISR vector. */
extern char isr_vector;

/** Default IRQ handler. This is weakly defined and can be overridden. */
void default_irq_handler(void);

/** Weakly defined interrput service routine vectors. These just alias to
 * default_irq_handler if not overridden. */
void irq_on_reset(void);
void irq_on_nmi(void);
void irq_on_exc(void);
void irq_on_systick(void);
void irq_on_swi(void);
void irq_on_tmr0(void);
void irq_on_gpio_a(void);
void irq_on_gpio_b(void);
void irq_on_spi0(void);
void irq_on_blel(void);
void irq_on_bleb(void);
void irq_on_usb(void);
void irq_on_tmr1(void);
void irq_on_tmr2(void);
void irq_on_uart0(void);
void irq_on_uart1(void);
void irq_on_rtc(void);
void irq_on_adc(void);
void irq_on_pwmx(void);
void irq_on_tmr3(void);
void irq_on_uart2(void);
void irq_on_uart3(void);
void irq_on_wdog_bat(void);

/*
 * Macro to define an interrput service routine.
 */
#define IRQ(name)                                                             \
  /* Real interrupt service routine. This contains most of the code to handle \
   * the interrupt. */                                                        \
  static void __attribute__((noinline)) _real__irq_on_##name(void);           \
  /* The actual routine that's jumped to. It's soley responsible for jumping  \
   * to the real handler (which requires multiple instructions because it's a \
   * long jump). This stub is compiled and linked promimal to the ISR vector. \
   */                                                                         \
  void __attribute__((interrupt))                                             \
  __attribute__((__section__(".isr_vector.routines"))) irq_on_##name(void)             \
  {                                                                           \
    _real__irq_on_##name();                                                   \
  }                                                                           \
  static void __attribute__((noinline)) _real__irq_on_##name(void)

inline static void enable_interrupts()
{
  int mstatus;
  asm volatile ("csrr %0, mstatus" : "=r"(mstatus));
  mstatus |= 0x88;
  asm volatile ("csrw mstatus, %0" : : "r"(mstatus));
}

inline static void disable_interrupts()
{
  int mstatus;
  asm volatile ("csrr %0, mstatus" : "=r"(mstatus));
  mstatus &= ~0x88;
  asm volatile ("csrw mstatus, %0" : : "r"(mstatus));
}