Intel® Quark™ Microcontroller Software Interface 1.4.0 Intel® Quark™ Microcontroller BSP

- Main Page
- Modules
- Data Structures
- Files

- File List

idt.h
1 /*
2 * {% copyright %}
3 */
4 #ifndef __IDT_H__
5 #define __IDT_H__
6
7 #include <stdint.h>
8 #include <string.h>
9 #include "qm_common.h"
10 #include "qm_soc_regs.h"
11
12 #if (QUARK_SE)
13 #define IDT_NUM_GATES (68)
14 #elif(QUARK_D2000)
15 #define IDT_NUM_GATES (52)
16 #endif
17
18 #define IDT_SIZE (sizeof(intr_gate_desc_t) * IDT_NUM_GATES)
19
20 typedef struct idtr {
21 uint16_t limit;
22 uint32_t base;
23 } __attribute__((packed)) idtr_t;
24
25 typedef struct intr_gate_desc {
26 uint16_t isr_low;
27 uint16_t selector; /* Segment selector */
28
29 /* The format of conf is the following:
30
31 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
32 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
33 |p |dpl |ss|d |type | unused |
34
35 type: Gate type
36 d: size of Gate
37 ss: Storage Segment
38 dpl: Descriptor Privilege level
39 p: Segment present level
40 */
41 uint16_t conf;
42 uint16_t isr_high;
43 } __attribute__((packed)) intr_gate_desc_t;
44
45 extern intr_gate_desc_t __idt_start[];
46
47 /*
48 * Setup IDT gate as an interrupt descriptor and assing the ISR entry point
49 */
50 static __inline__ void idt_set_intr_gate_desc(uint32_t vector, uint32_t isr)
51 {
52 intr_gate_desc_t *desc;
53 idtr_t idtr;
54
55 desc = __idt_start + vector;
56
57 desc->isr_low = isr & 0xFFFF;
58 desc->selector = 0x08; /* Code segment offset in GDT */
59
60 desc->conf = 0x8E00; /* type: 0b11 (Interrupt)
61 d: 1 (32 bits)
62 ss: 0
63 dpl: 0
64 p: 1
65 */
66 desc->isr_high = (isr >> 16) & 0xFFFF;
67
68 /* The following reloads the IDTR register. If a lookaside buffer is
69 * being used this will invalidate it. This is required as it's possible
70 * for an application to change the registered ISR. */
71 idtr.limit = IDT_SIZE - 1;
72 idtr.base = (uint32_t)__idt_start;
73 __asm__ __volatile__("lidt %0\n\t" ::"m"(idtr));
74 }
75
76 /*
77 * Initialize Interrupt Descriptor Table.
78 * The IDT is initialized with null descriptors: any interrupt at this stage
79 * will cause a triple fault.
80 */
81 static __inline__ void idt_init(void)
82 {
83 idtr_t idtr;
84
85 memset(__idt_start, 0x00, IDT_SIZE);
86
87 /* Initialize idtr structure */
88 idtr.limit = IDT_SIZE - 1;
89 idtr.base = (uint32_t)__idt_start;
90
91 /* Load IDTR register */
92 __asm__ __volatile__("lidt %0\n\t" ::"m"(idtr));
93 }
94 #endif /* __IDT_H__ */