source: rtems/bsps/x86_64/amd64/interrupts/idt.c @ 6869321

5
Last change on this file since 6869321 was 6869321, checked in by Amaan Cheval <amaan.cheval@…>, on 08/13/18 at 10:50:38

bsps/x86_64: Add support for RTEMS interrupts

Updates #2898.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 * Copyright (c) 2018.
3 * Amaan Cheval <amaan.cheval@gmail.com>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <stdint.h>
28#include <rtems.h>
29#include <rtems/score/idt.h>
30#include <rtems/score/basedefs.h>
31#include <rtems/score/x86_64.h>
32#include <rtems/score/cpuimpl.h>
33#include <bsp/irq-generic.h>
34
35/*
36 * The IDT maps every interrupt vector to an interrupt_descriptor based on the
37 * vector number.
38 */
39interrupt_descriptor amd64_idt[IDT_SIZE] RTEMS_ALIGNED(8) = { { 0 } };
40
41struct idt_record idtr = {
42  .limit = (IDT_SIZE * 16) - 1,
43  .base = (uintptr_t) amd64_idt
44};
45
46/**
47 * IRQs that the RTEMS Interrupt Manager will manage
48 * @see DISTINCT_INTERRUPT_ENTRY
49 */
50static uintptr_t rtemsIRQs[BSP_IRQ_VECTOR_NUMBER] = {
51  (uintptr_t) rtems_irq_prologue_0,
52  (uintptr_t) rtems_irq_prologue_1,
53  (uintptr_t) rtems_irq_prologue_2,
54  (uintptr_t) rtems_irq_prologue_3,
55  (uintptr_t) rtems_irq_prologue_4,
56  (uintptr_t) rtems_irq_prologue_5,
57  (uintptr_t) rtems_irq_prologue_6,
58  (uintptr_t) rtems_irq_prologue_7,
59  (uintptr_t) rtems_irq_prologue_8,
60  (uintptr_t) rtems_irq_prologue_9,
61  (uintptr_t) rtems_irq_prologue_10,
62  (uintptr_t) rtems_irq_prologue_11,
63  (uintptr_t) rtems_irq_prologue_12,
64  (uintptr_t) rtems_irq_prologue_13,
65  (uintptr_t) rtems_irq_prologue_14,
66  (uintptr_t) rtems_irq_prologue_15,
67  (uintptr_t) rtems_irq_prologue_16,
68  (uintptr_t) rtems_irq_prologue_17,
69  (uintptr_t) rtems_irq_prologue_18,
70  (uintptr_t) rtems_irq_prologue_19,
71  (uintptr_t) rtems_irq_prologue_20,
72  (uintptr_t) rtems_irq_prologue_21,
73  (uintptr_t) rtems_irq_prologue_22,
74  (uintptr_t) rtems_irq_prologue_23,
75  (uintptr_t) rtems_irq_prologue_24,
76  (uintptr_t) rtems_irq_prologue_25,
77  (uintptr_t) rtems_irq_prologue_26,
78  (uintptr_t) rtems_irq_prologue_27,
79  (uintptr_t) rtems_irq_prologue_28,
80  (uintptr_t) rtems_irq_prologue_29,
81  (uintptr_t) rtems_irq_prologue_30,
82  (uintptr_t) rtems_irq_prologue_31,
83  (uintptr_t) rtems_irq_prologue_32
84};
85
86void lidt(struct idt_record *ptr)
87{
88  __asm__ volatile ("lidt %0" :: "m"(*ptr));
89}
90
91interrupt_descriptor amd64_create_interrupt_descriptor(
92  uintptr_t handler, uint8_t types_and_attributes
93)
94{
95  interrupt_descriptor entry = {
96    .offset_0 = handler & 0xffff,
97    .segment_selector = amd64_get_cs(),
98    .interrupt_stack_table = 0,
99    .type_and_attributes = types_and_attributes,
100    .offset_1 = (handler >> 16) & 0xffff,
101    .offset_2 = handler >> 32,
102    .reserved_zero = 0,
103  };
104  return entry;
105}
106
107uintptr_t amd64_get_handler_from_idt(uint32_t vector)
108{
109  interrupt_descriptor entry = amd64_idt[vector];
110  uintptr_t handler = entry.offset_0 | (entry.offset_1 << 16) |
111    ((uint64_t) entry.offset_2 << 32);
112  return handler;
113}
114
115void amd64_install_raw_interrupt(
116  uint32_t vector, uintptr_t new_handler, uintptr_t *old_handler
117)
118{
119  *old_handler = amd64_get_handler_from_idt(vector);
120  interrupt_descriptor new_desc = amd64_create_interrupt_descriptor(
121    new_handler,
122    IDT_INTERRUPT_GATE | IDT_PRESENT
123  );
124  amd64_idt[vector] = new_desc;
125}
126
127void amd64_dispatch_isr(rtems_vector_number vector)
128{
129  bsp_interrupt_handler_dispatch(vector);
130}
131
132rtems_status_code bsp_interrupt_facility_initialize(void)
133{
134  uintptr_t old;
135  for (uint32_t i = 0; i < BSP_IRQ_VECTOR_NUMBER; i++) {
136    amd64_install_raw_interrupt(i, rtemsIRQs[i], &old);
137  }
138
139  lidt(&idtr);
140
141  return RTEMS_SUCCESSFUL;
142}
143
144void bsp_interrupt_vector_disable(rtems_vector_number vector)
145{
146  /* XXX */
147}
148void bsp_interrupt_vector_enable(rtems_vector_number vector)
149{
150  /* XXX */
151}
Note: See TracBrowser for help on using the repository browser.