KernOS
interrupt.h
Go to the documentation of this file.
1 //
2 // Created on 5/19/20.
3 //
4 
5 #ifndef KERNOS_INTERRUPT_H
6 #define KERNOS_INTERRUPT_H
7 
8 #include <common.h>
9 #include <utilities.h>
10 #include <registers.h>
11 #include <ports.h>
12 #include <pic.h>
13 
16 namespace INTRP // interrupt
17 {
18  enum IVT : uint8_t
19  {
20  // reserve exceptions
23  DEBUG_TRAP = 0x1,
24  NMI_INTERRUPT = 0x2,
26  OVERFLOW_TRAP = 0x4,
30  DOUBLE_FAULT = 0x8,
34  STACK_SEG_FAULT = 0x0C,
36  PAGE_FAULT = 0x0E,
37  RESERVED = 0x0F,
38  MATH_FAULT = 0x10,
42  RESERVED_END = 0x1F,
43 
44  // user-defined interrupts
45  PIC1_OFFSET = 0x20,
47  TIMER = 0x20,
48  KEYBOARD = 0x21,
49  PIC2_CASCADE = 0x22,
50  SERIAL2 = 0x23,
51  SERIAL1 = 0x24,
52  PARALLEL2 = 0x25,
53  DISKETTE = 0x26,
54  PARALLEL1 = 0x27,
55 
56  PIC2_OFFSET = 0x28,
57  CMOS = 0x28,
58  CGA = 0x29,
59  RESERVED1 = 0x2A,
60  RESERVED2 = 0x2B,
61  PS2 = 0x2C,
62  FPU = 0x2D,
63  HARDDISK = 0x2E,
64  RESERVED3 = 0x2F,
65 
67  };
68 
69  static_assert(IVT::USER_DEFINED_START == (IVT::RESERVED_END + 1));
70 
71  const uint16_t IDT_ENTRIES = 256;
72 
83  union [[gnu::packed]] DescriptorEntry
84  {
85  struct
86  {
87  uint16_t m_OffsetLow;
88  uint16_t m_CS_Selector;
89  uint8_t m_Reserve;
90  uint8_t m_Access;
91  uint16_t m_OffsetHigh;
92  };
93  struct
94  {
95  uint32_t Low;
96  uint32_t High;
97  };
98  };
99 
103  class Mask
104  {
105  private:
106  bool m_InterruptFlag;
107 
108  public:
109  Mask() : m_InterruptFlag (FlagsRegister() & FLAGS::IF)
110  {
111 #ifndef TEST_BUILD // TODO: have cleaner test_build setup
112  cli();
113 #endif
114  }
115 
117  {
118 #ifndef TEST_BUILD
119  if (m_InterruptFlag) // restore interrupts if enabled previously
120  sti();
121 #endif
122  }
123 
124  };
125 
126  void RegisterHandler(DescriptorEntry IdtTable[], size_t Idx, func_ptr Handler);
127 
128 } // namespace INTRP
129 
130 struct IrqPort
131 {
132  uint16_t m_CsrPort {0};
133  uint16_t m_DataPort {0};
134  uint8_t m_IrqNumber {0};
135 
136  consteval IrqPort (const INTRP::IVT Irq)
137  {
138  if (Irq < INTRP::IVT::PIC1_OFFSET)
139  {
140  }
141  else if (Irq < INTRP::IVT::PIC2_OFFSET)
142  {
143  m_CsrPort = PORTS::PIC1_COMMAND;
144  m_DataPort = PORTS::PIC1_DATA;
145  m_IrqNumber = Irq - INTRP::IVT::PIC1_OFFSET;
146  }
147  else
148  {
149  m_CsrPort = PORTS::PIC2_COMMAND;
150  m_DataPort = PORTS::PIC2_DATA;
151  m_IrqNumber = Irq - INTRP::IVT::PIC2_OFFSET;
152  }
153  }
154 };
155 
156 inline void UnmaskInterrupt (const IrqPort Irq)
157 {
158  uint8_t Imr = in8(Irq.m_DataPort);
159 
160  Imr &= ~(1 << Irq.m_IrqNumber);
161 
162  out8(Irq.m_DataPort, Imr);
163 }
164 
165 class IRQScope
166 {
167 private:
168  const IrqPort m_Irq;
169 
170 public:
171  explicit IRQScope (const IrqPort IRQNumber) :
172  m_Irq (IRQNumber)
173  {
174  }
175 
177  {
179  }
180 };
181 
182 
183 namespace INIT
184 {
192  void idt();
193 }
194 
195 
196 #endif //KERNOS_INTERRUPT_H
uint16_t m_CS_Selector
Definition: interrupt.h:88
interrupt enable flag
Definition: registers.h:61
void RegisterHandler(DescriptorEntry IdtTable[], size_t Idx, func_ptr Handler)
Creates interrupt descriptor entries in idt_table, and loads into CPU.
Definition: interrupt.cpp:29
uint32_t High
Definition: interrupt.h:96
uint16_t m_OffsetHigh
Definition: interrupt.h:91
IRQScope(const IrqPort IRQNumber)
Definition: interrupt.h:171
void(*)() func_ptr
Definition: ktypes.h:16
void idt()
Creates interrupt descriptor table and loads to CPU.
Definition: interrupt.cpp:126
interrupt namespace
Definition: interrupt.h:16
~IRQScope()
Definition: interrupt.h:176
Disables interrupt on construction, restores previous interrupt mask on scope exit.
Definition: interrupt.h:103
uint8_t m_Access
Definition: interrupt.h:90
uint16_t m_DataPort
Definition: interrupt.h:133
uint8_t m_Reserve
Definition: interrupt.h:89
const uint16_t IDT_ENTRIES
Definition: interrupt.h:71
uint32_t Low
Definition: interrupt.h:95
uint8_t m_IrqNumber
Definition: interrupt.h:134
contains all kernel initialization routines
Definition: cpu.h:10
void UnmaskInterrupt(const IrqPort Irq)
Definition: interrupt.h:156
Timer namespace.
Definition: pit.h:10
CPU Flags register.
Definition: registers.h:51
uint16_t m_OffsetLow
Definition: interrupt.h:87
consteval IrqPort(const INTRP::IVT Irq)
Definition: interrupt.h:136
Exception and interrupt gate descriptor entry.
Definition: interrupt.h:83
uint16_t m_CsrPort
Definition: interrupt.h:132