Pip
Architecture-dependent parts of Pip: MAL, IAL and boot
Data Structures | Macros | Functions | Variables
idt.c File Reference
#include "idt.h"
#include "port.h"
#include "pic8259.h"
#include "debug.h"
#include "libc.h"
#include "Internal.h"
#include "x86int.h"
#include "asm_int.h"
#include "segment_selectors.h"
#include "gdt.h"
#include "Services.h"
#include "pip_interrupt_calls.h"

Data Structures

struct  idt_callback_conf_s
 

Macros

#define DOUBLE_FAULT_LEVEL   8
 
#define IRQ_CODE_SEGMENT   KERNEL_CODE_SEGMENT_SELECTOR
 
#define IDT_INTERRUPT_ENTRY(callback_index)
 IDT interrupt entry initializer. idt_int_trap_entry_t Notice that the only difference with the IDT_TRAP_ENTRY macro is the type field. More...
 
#define IDT_TRAP_ENTRY(callback_index)
 IDT trap entry initializer. idt_int_trap_entry_t Notice that the only difference with the IDT_INTERRUPT_ENTRY macro is the type field Trap gates do not clear the interrupt flag when accessed. More...
 
#define PIC1_OFFSET   0x20
 
#define PIC2_OFFSET   0x28
 

Functions

void hardwareInterruptHandler (int_ctx_t *ctx)
 
void softwareInterruptHandler (int_ctx_t *ctx)
 
void propagateFault (page callerPartDesc, page callerPageDir, unsigned targetInterrupt, unsigned callerContextSaveIndex, unsigned nbL, interruptMask flagsOnYield, interruptMask flagsOnWake, user_ctx_t *callerInterruptedContext)
 
void faultInterruptHandler (int_ctx_t *ctx)
 
void initIDT (void)
 
void remapIRQ (void)
 
void timerPhase (uint32_t hz)
 
static void cpuid (int code, uint32_t *a, uint32_t *d)
 
static int cpuid_string (int code, uint32_t where[4])
 
void initCPU ()
 
void idt_init (void)
 

Variables

static struct idt_callback_conf_s idt_callbacks [256]
 IRQ callbacks, privilege, and segment table This table associates IRQ numbers to handlers, as well as their privilege level and their segment (configured in the GDT). More...
 
static idt_entry_t idt_entries [256]
 
uint32_t pcid_enabled = 0
 
uint32_t timer_ticks = 0
 

Macro Definition Documentation

◆ DOUBLE_FAULT_LEVEL

#define DOUBLE_FAULT_LEVEL   8

◆ IDT_INTERRUPT_ENTRY

#define IDT_INTERRUPT_ENTRY (   callback_index)
Value:
.interrupt = { \
(((uint32_t) idt_callbacks[callback_index].callback) & 0xFFFF), \
(idt_callbacks[callback_index].segment), \
0, \
0, \
(idt_callbacks[callback_index].dpl), \
1, \
((((uint32_t) idt_callbacks[callback_index].callback) >> 16) & 0xFFFF) \
} \
}
#define INTERRUPT_GATE_TYPE
Definition: idt.h:84
union idt_entry_u idt_entry_t
Definition: idt.h:81
static struct idt_callback_conf_s idt_callbacks[256]
IRQ callbacks, privilege, and segment table This table associates IRQ numbers to handlers, as well as their privilege level and their segment (configured in the GDT).
Definition: idt.c:247

IDT interrupt entry initializer. idt_int_trap_entry_t Notice that the only difference with the IDT_TRAP_ENTRY macro is the type field.

◆ IDT_TRAP_ENTRY

#define IDT_TRAP_ENTRY (   callback_index)
Value:
.trap = { \
(((uint32_t) idt_callbacks[callback_index].callback) & 0xFFFF), \
(idt_callbacks[callback_index].segment), \
0, \
0, \
TRAP_GATE_TYPE, \
idt_callbacks[callback_index].dpl, \
1, \
((((uint32_t) idt_callbacks[callback_index].callback) >> 16) & 0xFFFF) \
} \
}
union idt_entry_u idt_entry_t
Definition: idt.h:81
static struct idt_callback_conf_s idt_callbacks[256]
IRQ callbacks, privilege, and segment table This table associates IRQ numbers to handlers, as well as their privilege level and their segment (configured in the GDT).
Definition: idt.c:247

IDT trap entry initializer. idt_int_trap_entry_t Notice that the only difference with the IDT_INTERRUPT_ENTRY macro is the type field Trap gates do not clear the interrupt flag when accessed.

◆ IRQ_CODE_SEGMENT

#define IRQ_CODE_SEGMENT   KERNEL_CODE_SEGMENT_SELECTOR

◆ PIC1_OFFSET

#define PIC1_OFFSET   0x20

◆ PIC2_OFFSET

#define PIC2_OFFSET   0x28

Function Documentation

◆ cpuid()

static void cpuid ( int  code,
uint32_t *  a,
uint32_t *  d 
)
inlinestatic

issue a single request to CPUID. Fits 'intel features', for instance note that even if only "eax" and "edx" are of interest, other registers will be modified by the operation, so we need to tell the compiler about it.

◆ cpuid_string()

static int cpuid_string ( int  code,
uint32_t  where[4] 
)
inlinestatic

issue a complete request, storing general registers output as a string

◆ faultInterruptHandler()

void faultInterruptHandler ( int_ctx_t ctx)

◆ hardwareInterruptHandler()

void hardwareInterruptHandler ( int_ctx_t ctx)

◆ idt_init()

void idt_init ( void  )

◆ initCPU()

void initCPU ( )

◆ initIDT()

void initIDT ( void  )

Dynamic initialization of the IDT could be done statically through some obscure relative address black magic "https://wiki.osdev.org/IDT_problems#what_does_.22shift_operator_may_only_be_applied_to_scalar_values.22_mean.3F"

< Pointer to the IDT

◆ propagateFault()

void propagateFault ( page  callerPartDesc,
page  callerPageDir,
unsigned  targetInterrupt,
unsigned  callerContextSaveIndex,
unsigned  nbL,
interruptMask  flagsOnYield,
interruptMask  flagsOnWake,
user_ctx_t callerInterruptedContext 
)

◆ remapIRQ()

void remapIRQ ( void  )

◆ softwareInterruptHandler()

void softwareInterruptHandler ( int_ctx_t ctx)

◆ timerPhase()

void timerPhase ( uint32_t  hz)

Variable Documentation

◆ idt_callbacks

struct idt_callback_conf_s idt_callbacks[256]
static

IRQ callbacks, privilege, and segment table This table associates IRQ numbers to handlers, as well as their privilege level and their segment (configured in the GDT).

Some segment selector stuff :

  • Faults are in kernel ring, because we won't explicitely trigger them from userland.
  • But pipcalls may be triggered on purpose from userland (well, they should always be, in fact), so the other handlers' ring is USER (3).

◆ idt_entries

idt_entry_t idt_entries[256]
static

Interrupt Descriptor Table Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 3a - 6.10

◆ pcid_enabled

uint32_t pcid_enabled = 0

◆ timer_ticks

uint32_t timer_ticks = 0