Contiki 3.x
idt.c
1 /*
2  * Copyright (C) 2015, Intel Corporation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "gdt-layout.h"
32 #include "prot-domains.h"
33 #include <stdint.h>
34 
35 #include "helpers.h"
36 #include "segmentation.h"
37 #include "idt.h"
38 
39 #define NUM_DESC 256
40 
41 typedef struct idtr {
42  uint16_t limit;
43  uint32_t base;
44 } __attribute__((packed)) idtr_t;
45 
46 typedef union intr_gate_desc {
47  struct __attribute__((packed)) {
48  uint16_t offset_low;
49  uint16_t selector; /* Segment Selector for destination code segment */
50  uint16_t fixed:11;
51  uint16_t d:1; /* Size of gate: 1 = 32 bits; 0 = 16 bits */
52  uint16_t pad:1;
53  uint16_t dpl:2; /* Descriptor Privilege Level */
54  uint16_t p:1; /* Segment Present flag */
55  uint16_t offset_high;
56  };
57  uint64_t raw;
58  struct {
59  uint32_t raw_lo;
60  uint32_t raw_hi;
61  };
62 } intr_gate_desc_t;
63 
64 /* According to Intel Combined Manual, Vol. 3, Section 6.10, the base addresses
65  * of the IDT should be aligned on an 8-byte boundary to maximize performance
66  * of cache line fills.
67  */
68 static intr_gate_desc_t __attribute__((aligned(8))) ATTR_BSS_KERN
69  idt[NUM_DESC];
70 
71 /*---------------------------------------------------------------------------*/
72 /* XXX: If you change this function prototype, make sure you fix the assembly
73  * code in SET_INT_EXC_HANDLER macro in interrupt.h. Otherwise, you might
74  * face a very-hard-to-find bug in the interrupt handling system.
75  */
76 void
77 idt_set_intr_gate_desc(int intr_num,
78  uint32_t offset,
79  uint16_t cs,
80  uint16_t dpl)
81 {
82  intr_gate_desc_t desc;
83 
84  desc.offset_low = offset & 0xFFFF;
85  desc.selector = cs;
86  desc.fixed = BIT(9) | BIT(10);
87  desc.pad = 0;
88  desc.d = 1;
89  desc.dpl = dpl;
90  desc.p = 1;
91  desc.offset_high = (offset >> 16) & 0xFFFF;
92 
93  KERN_WRITEL(idt[intr_num].raw_hi, desc.raw_hi);
94  KERN_WRITEL(idt[intr_num].raw_lo, desc.raw_lo);
95 }
96 /*---------------------------------------------------------------------------*/
97 /* Initialize Interrupt Descriptor Table. The IDT is initialized with
98  * null descriptors. Therefore, any interrupt at this point will cause
99  * a triple fault.
100  */
101 void
102 idt_init(void)
103 {
104  idtr_t idtr;
105 
106  /* Initialize idtr structure */
107  idtr.limit = (sizeof(intr_gate_desc_t) * NUM_DESC) - 1;
108  idtr.base = KERN_DATA_OFF_TO_PHYS_ADDR((uint32_t)idt);
109 
110  /* Load IDTR register */
111  __asm__("lidt %0\n\t" :: "m" (idtr));
112 }
#define __attribute__(nothing)
Define attribute to nothing since it isn't handled by IAR.
Definition: iar.h:194
#define BIT(x)
Useful to reference a single bit of a byte.