Intel® Quark™ Microcontroller Software Interface  1.4.0
Intel® Quark™ Microcontroller BSP
qm_interrupt.h
1 /*
2  * {% copyright %}
3  */
4 
5 #ifndef __QM_INTERRUPT_H__
6 #define __QM_INTERRUPT_H__
7 
8 #include "qm_common.h"
9 #include "qm_soc_regs.h"
10 
11 #if (QM_SENSOR)
12 #include "qm_sensor_regs.h"
13 #endif
14 
15 /*
16  * Linear mapping between IRQs and interrupt vectors
17  */
18 #if (QUARK_SE)
19 #define QM_IRQ_TO_VECTOR(irq) (irq + 36) /* Get the vector of and IRQ. */
20 
21 #elif(QUARK_D2000)
22 #define QM_IRQ_TO_VECTOR(irq) (irq + 32) /* Get the vector of and IRQ. */
23 
24 #endif
25 
26 /**
27  * Save IRQ context.
28  *
29  * On x86:
30  * - Save IOAPIC Redirection Table for all IRQs.
31  *
32  * On sensor:
33  * - Save interrupt enable, priority and trigger for all IRQs.
34  *
35  * @param[out] ctx IRQ context structure. This must not be NULL.
36  *
37  * @return Standard errno return type for QMSI.
38  * @retval 0 on success.
39  * @retval Negative @ref errno for possible error codes.
40  */
41 int qm_irq_save_context(qm_irq_context_t *const ctx);
42 
43 /**
44  * Restore IRQ context.
45  *
46  * On x86:
47  * Restore IOAPIC Redirection Table for all IRQs.
48  * Restore LAPIC to default configuration.
49  *
50  * On sensor:
51  * - Restore interrupt enable, priority and trigger for all IRQs.
52  *
53  * @param[in] ctx IRQ context structure. This must not be NULL.
54  *
55  * @return Standard errno return type for QMSI.
56  * @retval 0 on success.
57  * @retval Negative @ref errno for possible error codes.
58  */
59 int qm_irq_restore_context(const qm_irq_context_t *const ctx);
60 
61 /**
62  * Interrupt driver.
63  *
64  * @defgroup groupINT Interrupt
65  * @{
66  */
67 
68 /**
69  * Interrupt service routine type
70  */
71 typedef void (*qm_isr_t)(struct interrupt_frame *frame);
72 
73 /**
74  * Unconditionally enable interrupt delivery on the CPU.
75  */
76 void qm_irq_enable(void);
77 
78 /**
79  * Unconditionally disable interrupt delivery on the CPU.
80  */
81 void qm_irq_disable(void);
82 
83 /**
84  * Save interrupt state and disable all interrupts on the CPU.
85  *
86  * This routine disables interrupts. It can be called from either interrupt or
87  * non-interrupt context. This routine returns an architecture-dependent
88  * lock-out key representing the "interrupt disable state" prior to the call;
89  * this key can be passed to qm_irq_unlock() to re-enable interrupts.
90  *
91  * This function can be called recursively: it will return a key to return the
92  * state of interrupt locking to the previous level.
93  *
94  * @return An architecture-dependent lock-out key representing the "interrupt
95  * disable state" prior to the call.
96  *
97  */
98 unsigned int qm_irq_lock(void);
99 
100 /**
101  *
102  * Restore previous interrupt state on the CPU saved via qm_irq_lock().
103  *
104  * @param[in] key architecture-dependent lock-out key returned by a previous
105  * invocation of qm_irq_lock().
106  */
107 void qm_irq_unlock(unsigned int key);
108 
109 /**
110  * Unmask a given interrupt line.
111  *
112  * @param[in] irq Which IRQ to unmask.
113  */
114 void qm_irq_unmask(uint32_t irq);
115 
116 /**
117  * Mask a given interrupt line.
118  *
119  * @param[in] irq Which IRQ to mask.
120  */
121 void qm_irq_mask(uint32_t irq);
122 
123 void _qm_register_isr(uint32_t vector, qm_isr_t isr);
124 
125 void _qm_irq_setup(uint32_t irq);
126 
127 /*
128  * Request a given IRQ and register Interrupt Service Routine to interrupt
129  * vector.
130  *
131  * @param[in] irq IRQ number. Must be of type QM_IRQ_XXX.
132  * @param[in] isr ISR to register to given IRQ.
133  */
134 #if (QM_SENSOR)
135 #define QM_IRQ_REQUEST(irq, isr) \
136  do { \
137  _qm_register_isr(irq##_VECTOR, isr); \
138  _qm_irq_setup(irq); \
139  } while (0);
140 #else
141 #define QM_IRQ_REQUEST(irq, isr) \
142  do { \
143  qm_int_vector_request(irq##_VECTOR, isr); \
144  \
145  _qm_irq_setup(irq); \
146  } while (0)
147 #endif /* QM_SENSOR */
148 
149 /**
150  * Request an interrupt vector and register Interrupt Service Routine to it.
151  *
152  * @param[in] vector Vector number.
153  * @param[in] isr ISR to register to given IRQ.
154  */
155 #if (UNIT_TEST)
156 void qm_int_vector_request(uint32_t vector, qm_isr_t isr);
157 #else
158 #if (__iamcu__)
159 /*
160  * We assume that if the compiler supports the IAMCU ABI it also
161  * supports the 'interrupt' attribute.
162  */
163 static __inline__ void qm_int_vector_request(uint32_t vector, qm_isr_t isr)
164 {
165  _qm_register_isr(vector, isr);
166 }
167 
168 #else /* __iamcu__ */
169 
170 /*
171  * Using the standard SysV calling convention. A dummy (NULL in this case)
172  * parameter is added to ISR handler, to maintain consistency with the API
173  * imposed by the __attribute__((interrupt)) usage.
174  */
175 #define qm_int_vector_request(vector, isr) \
176  do { \
177  __asm__ __volatile__("push $1f\n\t" \
178  "push %0\n\t" \
179  "call %P1\n\t" \
180  "add $8, %%esp\n\t" \
181  "jmp 2f\n\t" \
182  ".align 4\n\t" \
183  "1:\n\t" \
184  " pushal\n\t" \
185  " push $0x00\n\t" \
186  " call %P2\n\t" \
187  " add $4, %%esp\n\t" \
188  " popal\n\t" \
189  " iret\n\t" \
190  "2:\n\t" ::"g"(vector), \
191  "i"(_qm_register_isr), "i"(isr) \
192  : "%eax", "%ecx", "%edx"); \
193  } while (0)
194 #endif /* __iamcu__ */
195 #endif /* UNIT_TEST */
196 
197 /**
198  * @}
199  */
200 #endif /* __QM_INTERRUPT_H__ */
void qm_irq_unlock(unsigned int key)
Restore previous interrupt state on the CPU saved via qm_irq_lock().
Definition: qm_interrupt.c:92
void qm_irq_unmask(uint32_t irq)
Unmask a given interrupt line.
Definition: qm_interrupt.c:125
unsigned int qm_irq_lock(void)
Save interrupt state and disable all interrupts on the CPU.
Definition: qm_interrupt.c:74
void(* qm_isr_t)(struct interrupt_frame *frame)
Interrupt service routine type.
Definition: qm_interrupt.h:71
void qm_irq_disable(void)
Unconditionally disable interrupt delivery on the CPU.
Definition: qm_interrupt.c:31
void qm_irq_mask(uint32_t irq)
Mask a given interrupt line.
Definition: qm_interrupt.c:111
void qm_irq_enable(void)
Unconditionally enable interrupt delivery on the CPU.
Definition: qm_interrupt.c:40
void qm_int_vector_request(uint32_t vector, qm_isr_t isr)
Request an interrupt vector and register Interrupt Service Routine to it.
Definition: qm_interrupt.h:163
SS IRQ context type.