mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 03:27:45 +00:00
Kernel: Add support for interrupts on x86_64
This commit is contained in:
parent
233ef26e4d
commit
065c6c307d
4 changed files with 98 additions and 19 deletions
|
@ -116,9 +116,15 @@ struct [[gnu::packed]] IDTEntry
|
||||||
u16 offset_1; // offset bits 0..15
|
u16 offset_1; // offset bits 0..15
|
||||||
u16 selector; // a code segment selector in GDT or LDT
|
u16 selector; // a code segment selector in GDT or LDT
|
||||||
|
|
||||||
u8 zero; // unused, set to 0 (maybe used on amd64)
|
#if ARCH(I386)
|
||||||
|
u8 zero; // unused, set to 0
|
||||||
|
#else
|
||||||
|
struct {
|
||||||
|
u8 interrupt_stack_table : 3;
|
||||||
|
u8 zero : 5; // unused, set to 0
|
||||||
|
};
|
||||||
|
#endif
|
||||||
struct {
|
struct {
|
||||||
// FIXME: Is the order correct?
|
|
||||||
u8 gate_type : 4;
|
u8 gate_type : 4;
|
||||||
u8 storage_segment : 1;
|
u8 storage_segment : 1;
|
||||||
u8 descriptor_privilege_level : 2;
|
u8 descriptor_privilege_level : 2;
|
||||||
|
@ -126,7 +132,6 @@ struct [[gnu::packed]] IDTEntry
|
||||||
} type_attr; // type and attributes
|
} type_attr; // type and attributes
|
||||||
u16 offset_2; // offset bits 16..31
|
u16 offset_2; // offset bits 16..31
|
||||||
#if !ARCH(I386)
|
#if !ARCH(I386)
|
||||||
// we may need to switch those around?
|
|
||||||
u32 offset_3;
|
u32 offset_3;
|
||||||
u32 zeros;
|
u32 zeros;
|
||||||
#endif
|
#endif
|
||||||
|
@ -135,6 +140,9 @@ struct [[gnu::packed]] IDTEntry
|
||||||
IDTEntry(FlatPtr callback, u16 selector_, IDTEntryType type, u8 storage_segment, u8 privilege_level)
|
IDTEntry(FlatPtr callback, u16 selector_, IDTEntryType type, u8 storage_segment, u8 privilege_level)
|
||||||
: offset_1 { (u16)((FlatPtr)callback & 0xFFFF) }
|
: offset_1 { (u16)((FlatPtr)callback & 0xFFFF) }
|
||||||
, selector { selector_ }
|
, selector { selector_ }
|
||||||
|
#if !ARCH(I386)
|
||||||
|
, interrupt_stack_table { 0 }
|
||||||
|
#endif
|
||||||
, zero { 0 }
|
, zero { 0 }
|
||||||
, type_attr {
|
, type_attr {
|
||||||
.gate_type = (u8)type,
|
.gate_type = (u8)type,
|
||||||
|
@ -150,7 +158,7 @@ struct [[gnu::packed]] IDTEntry
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 off()
|
FlatPtr off()
|
||||||
{
|
{
|
||||||
#if ARCH(I386)
|
#if ARCH(I386)
|
||||||
return (u32)offset_2 << 16 & (u32)offset_1;
|
return (u32)offset_2 << 16 & (u32)offset_1;
|
||||||
|
@ -165,4 +173,6 @@ struct [[gnu::packed]] IDTEntry
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
static_assert(sizeof(IDTEntry) == 2 * sizeof(void*));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
struct TrapFrame {
|
struct TrapFrame {
|
||||||
u32 prev_irq_level;
|
FlatPtr prev_irq_level;
|
||||||
TrapFrame* next_trap;
|
TrapFrame* next_trap;
|
||||||
RegisterState* regs; // must be last
|
RegisterState* regs; // must be last
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,32 @@ static EntropySource s_entropy_source_interrupts { EntropySource::Static::Interr
|
||||||
asm( \
|
asm( \
|
||||||
".globl " #title "_asm_entry\n" \
|
".globl " #title "_asm_entry\n" \
|
||||||
"" #title "_asm_entry: \n" \
|
"" #title "_asm_entry: \n" \
|
||||||
" cli;hlt;\n" \
|
" pushq %r15\n" \
|
||||||
);
|
" pushq %r14\n" \
|
||||||
|
" pushq %r13\n" \
|
||||||
|
" pushq %r12\n" \
|
||||||
|
" pushq %r11\n" \
|
||||||
|
" pushq %r10\n" \
|
||||||
|
" pushq %r9\n" \
|
||||||
|
" pushq %r8\n" \
|
||||||
|
" pushq %rax\n" \
|
||||||
|
" pushq %rcx\n" \
|
||||||
|
" pushq %rdx\n" \
|
||||||
|
" pushq %rbx\n" \
|
||||||
|
" pushq %rsp\n" \
|
||||||
|
" pushq %rbp\n" \
|
||||||
|
" pushq %rsi\n" \
|
||||||
|
" pushq %rdi\n" \
|
||||||
|
" pushq %rsp \n" /* set TrapFrame::regs */ \
|
||||||
|
" subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %rsp \n" \
|
||||||
|
" subq $0x8, %rsp\n" /* align stack */ \
|
||||||
|
" lea 0x8(%rsp), %rdi \n" \
|
||||||
|
" cld\n" \
|
||||||
|
" call enter_trap_no_irq \n" \
|
||||||
|
" lea 0x8(%rsp), %rdi \n" \
|
||||||
|
" call " #title "_handler\n" \
|
||||||
|
" addq $0x8, %rsp\n" /* undo alignment */\
|
||||||
|
" jmp common_trap_exit \n");
|
||||||
|
|
||||||
#define EH_ENTRY_NO_CODE(ec, title) \
|
#define EH_ENTRY_NO_CODE(ec, title) \
|
||||||
extern "C" void title##_handler(TrapFrame*); \
|
extern "C" void title##_handler(TrapFrame*); \
|
||||||
|
@ -109,8 +133,33 @@ static EntropySource s_entropy_source_interrupts { EntropySource::Static::Interr
|
||||||
asm( \
|
asm( \
|
||||||
".globl " #title "_asm_entry\n" \
|
".globl " #title "_asm_entry\n" \
|
||||||
"" #title "_asm_entry: \n" \
|
"" #title "_asm_entry: \n" \
|
||||||
" cli;hlt;\n" \
|
" pushq $0x0\n" \
|
||||||
);
|
" pushq %r15\n" \
|
||||||
|
" pushq %r14\n" \
|
||||||
|
" pushq %r13\n" \
|
||||||
|
" pushq %r12\n" \
|
||||||
|
" pushq %r11\n" \
|
||||||
|
" pushq %r10\n" \
|
||||||
|
" pushq %r9\n" \
|
||||||
|
" pushq %r8\n" \
|
||||||
|
" pushq %rax\n" \
|
||||||
|
" pushq %rcx\n" \
|
||||||
|
" pushq %rdx\n" \
|
||||||
|
" pushq %rbx\n" \
|
||||||
|
" pushq %rsp\n" \
|
||||||
|
" pushq %rbp\n" \
|
||||||
|
" pushq %rsi\n" \
|
||||||
|
" pushq %rdi\n" \
|
||||||
|
" pushq %rsp \n" /* set TrapFrame::regs */ \
|
||||||
|
" subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %rsp \n" \
|
||||||
|
" subq $0x8, %rsp\n" /* align stack */ \
|
||||||
|
" lea 0x8(%rsp), %rdi \n" \
|
||||||
|
" cld\n" \
|
||||||
|
" call enter_trap_no_irq \n" \
|
||||||
|
" lea 0x8(%rsp), %rdi \n" \
|
||||||
|
" call " #title "_handler\n" \
|
||||||
|
" addq $0x8, %rsp\n" /* undo alignment */\
|
||||||
|
" jmp common_trap_exit \n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
|
@ -10,15 +10,35 @@
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
asm(
|
asm(
|
||||||
".globl interrupt_common_asm_entry\n"
|
".globl interrupt_common_asm_entry\n"
|
||||||
"interrupt_common_asm_entry: \n"
|
"interrupt_common_asm_entry: \n"
|
||||||
" int3 \n" // FIXME
|
" hlt \n" // FIXME
|
||||||
".globl common_trap_exit \n"
|
".globl common_trap_exit \n"
|
||||||
"common_trap_exit: \n"
|
"common_trap_exit: \n"
|
||||||
// another thread may have handled this trap at this point, so don't
|
// another thread may have handled this trap at this point, so don't
|
||||||
// make assumptions about the stack other than there's a TrapFrame
|
// make assumptions about the stack other than there's a TrapFrame.
|
||||||
// and a pointer to it.
|
" movq %rsp, %rdi \n"
|
||||||
" call exit_trap \n"
|
" call exit_trap \n"
|
||||||
" int3 \n" // FIXME
|
" addq $" __STRINGIFY(TRAP_FRAME_SIZE) ", %rsp\n" // pop TrapFrame
|
||||||
|
".globl interrupt_common_asm_exit \n"
|
||||||
|
"interrupt_common_asm_exit: \n"
|
||||||
|
" popq %rdi\n"
|
||||||
|
" popq %rsi\n"
|
||||||
|
" popq %rbp\n"
|
||||||
|
" addq $8, %rsp\n" // skip restoring rsp
|
||||||
|
" popq %rbx\n"
|
||||||
|
" popq %rdx\n"
|
||||||
|
" popq %rcx\n"
|
||||||
|
" popq %rax\n"
|
||||||
|
" popq %r8\n"
|
||||||
|
" popq %r9\n"
|
||||||
|
" popq %r10\n"
|
||||||
|
" popq %r11\n"
|
||||||
|
" popq %r12\n"
|
||||||
|
" popq %r13\n"
|
||||||
|
" popq %r14\n"
|
||||||
|
" popq %r15\n"
|
||||||
|
" addq $0x8, %rsp\n" // skip exception_code, isr_number
|
||||||
|
" iretq\n"
|
||||||
);
|
);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue