diff options
Diffstat (limited to 'Kernel/Arch')
-rw-r--r-- | Kernel/Arch/i386/CPU.cpp | 621 | ||||
-rw-r--r-- | Kernel/Arch/i386/CPU.h | 153 | ||||
-rw-r--r-- | Kernel/Arch/i386/ISRStubs.h | 433 | ||||
-rw-r--r-- | Kernel/Arch/i386/Interrupts.h | 12 | ||||
-rw-r--r-- | Kernel/Arch/i386/ProcessorInfo.h | 4 |
5 files changed, 789 insertions, 434 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index 307338edcd..20d2cd205c 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -49,6 +49,7 @@ //#define PAGE_FAULT_DEBUG //#define CONTEXT_SWITCH_DEBUG +//#define SMP_DEBUG namespace Kernel { @@ -153,7 +154,7 @@ void handle_crash(RegisterState& regs, const char* description, int signal, bool auto process = Process::current(); if (!process) { klog() << description << " with !current"; - hang(); + Processor::halt(); } // If a process crashed while inspecting another process, @@ -166,7 +167,7 @@ void handle_crash(RegisterState& regs, const char* description, int signal, bool if (process->is_ring0()) { klog() << "Crash in ring 0 :("; dump_backtrace(); - hang(); + Processor::halt(); } cli(); @@ -291,7 +292,7 @@ void debug_handler(TrapFrame* trap) auto current_thread = Thread::current(); if (¤t_thread->process() == nullptr || (regs.cs & 3) == 0) { klog() << "Debug Exception in Ring0"; - hang(); + Processor::halt(); return; } constexpr u8 REASON_SINGLESTEP = 14; @@ -313,7 +314,7 @@ void breakpoint_handler(TrapFrame* trap) auto current_thread = Thread::current(); if (¤t_thread->process() == nullptr || (regs.cs & 3) == 0) { klog() << "Breakpoint Trap in Ring0"; - hang(); + Processor::halt(); return; } if (current_thread->tracer()) { @@ -336,7 +337,7 @@ void breakpoint_handler(TrapFrame* trap) asm("movl %%cr4, %%eax" \ : "=a"(cr4)); \ klog() << "CR0=" << String::format("%x", cr0) << " CR2=" << String::format("%x", cr2) << " CR3=" << String::format("%x", cr3) << " CR4=" << String::format("%x", cr4); \ - hang(); \ + Processor::halt(); \ } EH(2, "Unknown error") @@ -358,7 +359,7 @@ const DescriptorTablePointer& get_idtr() static void unimp_trap() { klog() << "Unhandled IRQ."; - hang(); + Processor::Processor::halt(); } GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number) @@ -374,6 +375,7 @@ static void revert_to_unused_handler(u8 interrupt_number) void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler) { + ASSERT(interrupt_number < GENERIC_INTERRUPT_HANDLERS_COUNT); if (s_interrupt_handler[interrupt_number] != nullptr) { if (s_interrupt_handler[interrupt_number]->type() == HandlerType::UnhandledInterruptHandler) { s_interrupt_handler[interrupt_number] = &handler; @@ -442,10 +444,7 @@ void flush_idt() static void idt_init() { s_idtr.address = s_idt; - s_idtr.limit = 0x100 * 8 - 1; - - for (u8 i = 0xff; i > 0x10; --i) - register_interrupt_handler(i, unimp_trap); + s_idtr.limit = 256 * 8 - 1; register_interrupt_handler(0x00, divide_error_asm_entry); register_user_callable_interrupt_handler(0x01, debug_asm_entry); @@ -465,134 +464,185 @@ static void idt_init() register_interrupt_handler(0x0f, _exception15); register_interrupt_handler(0x10, _exception16); - register_interrupt_handler(0x50, interrupt_0_asm_entry); - register_interrupt_handler(0x51, interrupt_1_asm_entry); - register_interrupt_handler(0x52, interrupt_2_asm_entry); - register_interrupt_handler(0x53, interrupt_3_asm_entry); - register_interrupt_handler(0x54, interrupt_4_asm_entry); - register_interrupt_handler(0x55, interrupt_5_asm_entry); - register_interrupt_handler(0x56, interrupt_6_asm_entry); - register_interrupt_handler(0x57, interrupt_7_asm_entry); - register_interrupt_handler(0x58, interrupt_8_asm_entry); - register_interrupt_handler(0x59, interrupt_9_asm_entry); - register_interrupt_handler(0x5a, interrupt_10_asm_entry); - register_interrupt_handler(0x5b, interrupt_11_asm_entry); - register_interrupt_handler(0x5c, interrupt_12_asm_entry); - register_interrupt_handler(0x5d, interrupt_13_asm_entry); - register_interrupt_handler(0x5e, interrupt_14_asm_entry); - register_interrupt_handler(0x5f, interrupt_15_asm_entry); - register_interrupt_handler(0x60, interrupt_16_asm_entry); - register_interrupt_handler(0x61, interrupt_17_asm_entry); - register_interrupt_handler(0x62, interrupt_18_asm_entry); - register_interrupt_handler(0x63, interrupt_19_asm_entry); - register_interrupt_handler(0x64, interrupt_20_asm_entry); - register_interrupt_handler(0x65, interrupt_21_asm_entry); - register_interrupt_handler(0x66, interrupt_22_asm_entry); - register_interrupt_handler(0x67, interrupt_23_asm_entry); - register_interrupt_handler(0x68, interrupt_24_asm_entry); - register_interrupt_handler(0x69, interrupt_25_asm_entry); - register_interrupt_handler(0x6a, interrupt_26_asm_entry); - register_interrupt_handler(0x6b, interrupt_27_asm_entry); - register_interrupt_handler(0x6c, interrupt_28_asm_entry); - register_interrupt_handler(0x6d, interrupt_29_asm_entry); - register_interrupt_handler(0x6e, interrupt_30_asm_entry); - register_interrupt_handler(0x6f, interrupt_31_asm_entry); - register_interrupt_handler(0x70, interrupt_32_asm_entry); - register_interrupt_handler(0x71, interrupt_33_asm_entry); - register_interrupt_handler(0x72, interrupt_34_asm_entry); - register_interrupt_handler(0x73, interrupt_35_asm_entry); - register_interrupt_handler(0x74, interrupt_36_asm_entry); - register_interrupt_handler(0x75, interrupt_37_asm_entry); - register_interrupt_handler(0x76, interrupt_38_asm_entry); - register_interrupt_handler(0x77, interrupt_39_asm_entry); - register_interrupt_handler(0x78, interrupt_40_asm_entry); - register_interrupt_handler(0x79, interrupt_41_asm_entry); - register_interrupt_handler(0x7a, interrupt_42_asm_entry); - register_interrupt_handler(0x7b, interrupt_43_asm_entry); - register_interrupt_handler(0x7c, interrupt_44_asm_entry); - register_interrupt_handler(0x7d, interrupt_45_asm_entry); - register_interrupt_handler(0x7e, interrupt_46_asm_entry); - register_interrupt_handler(0x7f, interrupt_47_asm_entry); - register_interrupt_handler(0x80, interrupt_48_asm_entry); - register_interrupt_handler(0x81, interrupt_49_asm_entry); - register_interrupt_handler(0x82, interrupt_50_asm_entry); - register_interrupt_handler(0x83, interrupt_51_asm_entry); - register_interrupt_handler(0x84, interrupt_52_asm_entry); - register_interrupt_handler(0x85, interrupt_53_asm_entry); - register_interrupt_handler(0x86, interrupt_54_asm_entry); - register_interrupt_handler(0x87, interrupt_55_asm_entry); - register_interrupt_handler(0x88, interrupt_56_asm_entry); - register_interrupt_handler(0x89, interrupt_57_asm_entry); - register_interrupt_handler(0x8a, interrupt_58_asm_entry); - register_interrupt_handler(0x8b, interrupt_59_asm_entry); - register_interrupt_handler(0x8c, interrupt_60_asm_entry); - register_interrupt_handler(0x8d, interrupt_61_asm_entry); - register_interrupt_handler(0x8e, interrupt_62_asm_entry); - register_interrupt_handler(0x8f, interrupt_63_asm_entry); - register_interrupt_handler(0x90, interrupt_64_asm_entry); - register_interrupt_handler(0x91, interrupt_65_asm_entry); - register_interrupt_handler(0x92, interrupt_66_asm_entry); - register_interrupt_handler(0x93, interrupt_67_asm_entry); - register_interrupt_handler(0x94, interrupt_68_asm_entry); - register_interrupt_handler(0x95, interrupt_69_asm_entry); - register_interrupt_handler(0x96, interrupt_70_asm_entry); - register_interrupt_handler(0x97, interrupt_71_asm_entry); - register_interrupt_handler(0x98, interrupt_72_asm_entry); - register_interrupt_handler(0x99, interrupt_73_asm_entry); - register_interrupt_handler(0x9a, interrupt_74_asm_entry); - register_interrupt_handler(0x9b, interrupt_75_asm_entry); - register_interrupt_handler(0x9c, interrupt_76_asm_entry); - register_interrupt_handler(0x9d, interrupt_77_asm_entry); - register_interrupt_handler(0x9e, interrupt_78_asm_entry); - register_interrupt_handler(0x9f, interrupt_79_asm_entry); - register_interrupt_handler(0xa0, interrupt_80_asm_entry); - register_interrupt_handler(0xa1, interrupt_81_asm_entry); - register_interrupt_handler(0xa2, interrupt_82_asm_entry); - register_interrupt_handler(0xa3, interrupt_83_asm_entry); - register_interrupt_handler(0xa4, interrupt_84_asm_entry); - register_interrupt_handler(0xa5, interrupt_85_asm_entry); - register_interrupt_handler(0xa6, interrupt_86_asm_entry); - register_interrupt_handler(0xa7, interrupt_87_asm_entry); - register_interrupt_handler(0xa8, interrupt_88_asm_entry); - register_interrupt_handler(0xa9, interrupt_89_asm_entry); - register_interrupt_handler(0xaa, interrupt_90_asm_entry); - register_interrupt_handler(0xab, interrupt_91_asm_entry); - register_interrupt_handler(0xac, interrupt_92_asm_entry); - register_interrupt_handler(0xad, interrupt_93_asm_entry); - register_interrupt_handler(0xae, interrupt_94_asm_entry); - register_interrupt_handler(0xaf, interrupt_95_asm_entry); - register_interrupt_handler(0xb0, interrupt_96_asm_entry); - register_interrupt_handler(0xb1, interrupt_97_asm_entry); - register_interrupt_handler(0xb2, interrupt_98_asm_entry); - register_interrupt_handler(0xb3, interrupt_99_asm_entry); - register_interrupt_handler(0xb4, interrupt_100_asm_entry); - register_interrupt_handler(0xb5, interrupt_101_asm_entry); - register_interrupt_handler(0xb6, interrupt_102_asm_entry); - register_interrupt_handler(0xb7, interrupt_103_asm_entry); - register_interrupt_handler(0xb8, interrupt_104_asm_entry); - register_interrupt_handler(0xb9, interrupt_105_asm_entry); - register_interrupt_handler(0xba, interrupt_106_asm_entry); - register_interrupt_handler(0xbb, interrupt_107_asm_entry); - register_interrupt_handler(0xbc, interrupt_108_asm_entry); - register_interrupt_handler(0xbd, interrupt_109_asm_entry); - register_interrupt_handler(0xbe, interrupt_110_asm_entry); - register_interrupt_handler(0xbf, interrupt_111_asm_entry); - register_interrupt_handler(0xc0, interrupt_112_asm_entry); - register_interrupt_handler(0xc1, interrupt_113_asm_entry); - register_interrupt_handler(0xc2, interrupt_114_asm_entry); - register_interrupt_handler(0xc3, interrupt_115_asm_entry); - register_interrupt_handler(0xc4, interrupt_116_asm_entry); - register_interrupt_handler(0xc5, interrupt_117_asm_entry); - register_interrupt_handler(0xc6, interrupt_118_asm_entry); - register_interrupt_handler(0xc7, interrupt_119_asm_entry); - register_interrupt_handler(0xc8, interrupt_120_asm_entry); - register_interrupt_handler(0xc9, interrupt_121_asm_entry); - register_interrupt_handler(0xca, interrupt_122_asm_entry); - register_interrupt_handler(0xcb, interrupt_123_asm_entry); - register_interrupt_handler(0xcc, interrupt_124_asm_entry); - register_interrupt_handler(0xcd, interrupt_125_asm_entry); - register_interrupt_handler(0xce, interrupt_126_asm_entry); - register_interrupt_handler(0xcf, interrupt_127_asm_entry); + for (u8 i = 0x11; i < 0x50; i++) + register_interrupt_handler(i, unimp_trap); + + register_interrupt_handler(0x50, interrupt_80_asm_entry); + register_interrupt_handler(0x51, interrupt_81_asm_entry); + register_interrupt_handler(0x52, interrupt_82_asm_entry); + register_interrupt_handler(0x53, interrupt_83_asm_entry); + register_interrupt_handler(0x54, interrupt_84_asm_entry); + register_interrupt_handler(0x55, interrupt_85_asm_entry); + register_interrupt_handler(0x56, interrupt_86_asm_entry); + register_interrupt_handler(0x57, interrupt_87_asm_entry); + register_interrupt_handler(0x58, interrupt_88_asm_entry); + register_interrupt_handler(0x59, interrupt_89_asm_entry); + register_interrupt_handler(0x5a, interrupt_90_asm_entry); + register_interrupt_handler(0x5b, interrupt_91_asm_entry); + register_interrupt_handler(0x5c, interrupt_92_asm_entry); + register_interrupt_handler(0x5d, interrupt_93_asm_entry); + register_interrupt_handler(0x5e, interrupt_94_asm_entry); + register_interrupt_handler(0x5f, interrupt_95_asm_entry); + register_interrupt_handler(0x60, interrupt_96_asm_entry); + register_interrupt_handler(0x61, interrupt_97_asm_entry); + register_interrupt_handler(0x62, interrupt_98_asm_entry); + register_interrupt_handler(0x63, interrupt_99_asm_entry); + register_interrupt_handler(0x64, interrupt_100_asm_entry); + register_interrupt_handler(0x65, interrupt_101_asm_entry); + register_interrupt_handler(0x66, interrupt_102_asm_entry); + register_interrupt_handler(0x67, interrupt_103_asm_entry); + register_interrupt_handler(0x68, interrupt_104_asm_entry); + register_interrupt_handler(0x69, interrupt_105_asm_entry); + register_interrupt_handler(0x6a, interrupt_106_asm_entry); + register_interrupt_handler(0x6b, interrupt_107_asm_entry); + register_interrupt_handler(0x6c, interrupt_108_asm_entry); + register_interrupt_handler(0x6d, interrupt_109_asm_entry); + register_interrupt_handler(0x6e, interrupt_110_asm_entry); + register_interrupt_handler(0x6f, interrupt_111_asm_entry); + register_interrupt_handler(0x70, interrupt_112_asm_entry); + register_interrupt_handler(0x71, interrupt_113_asm_entry); + register_interrupt_handler(0x72, interrupt_114_asm_entry); + register_interrupt_handler(0x73, interrupt_115_asm_entry); + register_interrupt_handler(0x74, interrupt_116_asm_entry); + register_interrupt_handler(0x75, interrupt_117_asm_entry); + register_interrupt_handler(0x76, interrupt_118_asm_entry); + register_interrupt_handler(0x77, interrupt_119_asm_entry); + register_interrupt_handler(0x78, interrupt_120_asm_entry); + register_interrupt_handler(0x79, interrupt_121_asm_entry); + register_interrupt_handler(0x7a, interrupt_122_asm_entry); + register_interrupt_handler(0x7b, interrupt_123_asm_entry); + register_interrupt_handler(0x7c, interrupt_124_asm_entry); + register_interrupt_handler(0x7d, interrupt_125_asm_entry); + register_interrupt_handler(0x7e, interrupt_126_asm_entry); + register_interrupt_handler(0x7f, interrupt_127_asm_entry); + register_interrupt_handler(0x80, interrupt_128_asm_entry); + register_interrupt_handler(0x81, interrupt_129_asm_entry); + register_interrupt_handler(0x82, interrupt_130_asm_entry); + register_interrupt_handler(0x83, interrupt_131_asm_entry); + register_interrupt_handler(0x84, interrupt_132_asm_entry); + register_interrupt_handler(0x85, interrupt_133_asm_entry); + register_interrupt_handler(0x86, interrupt_134_asm_entry); + register_interrupt_handler(0x87, interrupt_135_asm_entry); + register_interrupt_handler(0x88, interrupt_136_asm_entry); + register_interrupt_handler(0x89, interrupt_137_asm_entry); + register_interrupt_handler(0x8a, interrupt_138_asm_entry); + register_interrupt_handler(0x8b, interrupt_139_asm_entry); + register_interrupt_handler(0x8c, interrupt_140_asm_entry); + register_interrupt_handler(0x8d, interrupt_141_asm_entry); + register_interrupt_handler(0x8e, interrupt_142_asm_entry); + register_interrupt_handler(0x8f, interrupt_143_asm_entry); + register_interrupt_handler(0x90, interrupt_144_asm_entry); + register_interrupt_handler(0x91, interrupt_145_asm_entry); + register_interrupt_handler(0x92, interrupt_146_asm_entry); + register_interrupt_handler(0x93, interrupt_147_asm_entry); + register_interrupt_handler(0x94, interrupt_148_asm_entry); + register_interrupt_handler(0x95, interrupt_149_asm_entry); + register_interrupt_handler(0x96, interrupt_150_asm_entry); + register_interrupt_handler(0x97, interrupt_151_asm_entry); + register_interrupt_handler(0x98, interrupt_152_asm_entry); + register_interrupt_handler(0x99, interrupt_153_asm_entry); + register_interrupt_handler(0x9a, interrupt_154_asm_entry); + register_interrupt_handler(0x9b, interrupt_155_asm_entry); + register_interrupt_handler(0x9c, interrupt_156_asm_entry); + register_interrupt_handler(0x9d, interrupt_157_asm_entry); + register_interrupt_handler(0x9e, interrupt_158_asm_entry); + register_interrupt_handler(0x9f, interrupt_159_asm_entry); + register_interrupt_handler(0xa0, interrupt_160_asm_entry); + register_interrupt_handler(0xa1, interrupt_161_asm_entry); + register_interrupt_handler(0xa2, interrupt_162_asm_entry); + register_interrupt_handler(0xa3, interrupt_163_asm_entry); + register_interrupt_handler(0xa4, interrupt_164_asm_entry); + register_interrupt_handler(0xa5, interrupt_165_asm_entry); + register_interrupt_handler(0xa6, interrupt_166_asm_entry); + register_interrupt_handler(0xa7, interrupt_167_asm_entry); + register_interrupt_handler(0xa8, interrupt_168_asm_entry); + register_interrupt_handler(0xa9, interrupt_169_asm_entry); + register_interrupt_handler(0xaa, interrupt_170_asm_entry); + register_interrupt_handler(0xab, interrupt_171_asm_entry); + register_interrupt_handler(0xac, interrupt_172_asm_entry); + register_interrupt_handler(0xad, interrupt_173_asm_entry); + register_interrupt_handler(0xae, interrupt_174_asm_entry); + register_interrupt_handler(0xaf, interrupt_175_asm_entry); + register_interrupt_handler(0xb0, interrupt_176_asm_entry); + register_interrupt_handler(0xb1, interrupt_177_asm_entry); + register_interrupt_handler(0xb2, interrupt_178_asm_entry); + register_interrupt_handler(0xb3, interrupt_179_asm_entry); + register_interrupt_handler(0xb4, interrupt_180_asm_entry); + register_interrupt_handler(0xb5, interrupt_181_asm_entry); + register_interrupt_handler(0xb6, interrupt_182_asm_entry); + register_interrupt_handler(0xb7, interrupt_183_asm_entry); + register_interrupt_handler(0xb8, interrupt_184_asm_entry); + register_interrupt_handler(0xb9, interrupt_185_asm_entry); + register_interrupt_handler(0xba, interrupt_186_asm_entry); + register_interrupt_handler(0xbb, interrupt_187_asm_entry); + register_interrupt_handler(0xbc, interrupt_188_asm_entry); + register_interrupt_handler(0xbd, interrupt_189_asm_entry); + register_interrupt_handler(0xbe, interrupt_190_asm_entry); + register_interrupt_handler(0xbf, interrupt_191_asm_entry); + register_interrupt_handler(0xc0, interrupt_192_asm_entry); + register_interrupt_handler(0xc1, interrupt_193_asm_entry); + register_interrupt_handler(0xc2, interrupt_194_asm_entry); + register_interrupt_handler(0xc3, interrupt_195_asm_entry); + register_interrupt_handler(0xc4, interrupt_196_asm_entry); + register_interrupt_handler(0xc5, interrupt_197_asm_entry); + register_interrupt_handler(0xc6, interrupt_198_asm_entry); + register_interrupt_handler(0xc7, interrupt_199_asm_entry); + register_interrupt_handler(0xc8, interrupt_200_asm_entry); + register_interrupt_handler(0xc9, interrupt_201_asm_entry); + register_interrupt_handler(0xca, interrupt_202_asm_entry); + register_interrupt_handler(0xcb, interrupt_203_asm_entry); + register_interrupt_handler(0xcc, interrupt_204_asm_entry); + register_interrupt_handler(0xcd, interrupt_205_asm_entry); + register_interrupt_handler(0xce, interrupt_206_asm_entry); + register_interrupt_handler(0xcf, interrupt_207_asm_entry); + register_interrupt_handler(0xd0, interrupt_208_asm_entry); + register_interrupt_handler(0xd1, interrupt_209_asm_entry); + register_interrupt_handler(0xd2, interrupt_210_asm_entry); + register_interrupt_handler(0xd3, interrupt_211_asm_entry); + register_interrupt_handler(0xd4, interrupt_212_asm_entry); + register_interrupt_handler(0xd5, interrupt_213_asm_entry); + register_interrupt_handler(0xd6, interrupt_214_asm_entry); + register_interrupt_handler(0xd7, interrupt_215_asm_entry); + register_interrupt_handler(0xd8, interrupt_216_asm_entry); + register_interrupt_handler(0xd9, interrupt_217_asm_entry); + register_interrupt_handler(0xda, interrupt_218_asm_entry); + register_interrupt_handler(0xdb, interrupt_219_asm_entry); + register_interrupt_handler(0xdc, interrupt_220_asm_entry); + register_interrupt_handler(0xdd, interrupt_221_asm_entry); + register_interrupt_handler(0xde, interrupt_222_asm_entry); + register_interrupt_handler(0xdf, interrupt_223_asm_entry); + register_interrupt_handler(0xe0, interrupt_224_asm_entry); + register_interrupt_handler(0xe1, interrupt_225_asm_entry); + register_interrupt_handler(0xe2, interrupt_226_asm_entry); + register_interrupt_handler(0xe3, interrupt_227_asm_entry); + register_interrupt_handler(0xe4, interrupt_228_asm_entry); + register_interrupt_handler(0xe5, interrupt_229_asm_entry); + register_interrupt_handler(0xe6, interrupt_230_asm_entry); + register_interrupt_handler(0xe7, interrupt_231_asm_entry); + register_interrupt_handler(0xe8, interrupt_232_asm_entry); + register_interrupt_handler(0xe9, interrupt_233_asm_entry); + register_interrupt_handler(0xea, interrupt_234_asm_entry); + register_interrupt_handler(0xeb, interrupt_235_asm_entry); + register_interrupt_handler(0xec, interrupt_236_asm_entry); + register_interrupt_handler(0xed, interrupt_237_asm_entry); + register_interrupt_handler(0xee, interrupt_238_asm_entry); + register_interrupt_handler(0xef, interrupt_239_asm_entry); + register_interrupt_handler(0xf0, interrupt_240_asm_entry); + register_interrupt_handler(0xf1, interrupt_241_asm_entry); + register_interrupt_handler(0xf2, interrupt_242_asm_entry); + register_interrupt_handler(0xf3, interrupt_243_asm_entry); + register_interrupt_handler(0xf4, interrupt_244_asm_entry); + register_interrupt_handler(0xf5, interrupt_245_asm_entry); + register_interrupt_handler(0xf6, interrupt_246_asm_entry); + register_interrupt_handler(0xf7, interrupt_247_asm_entry); + register_interrupt_handler(0xf8, interrupt_248_asm_entry); + register_interrupt_handler(0xf9, interrupt_249_asm_entry); + register_interrupt_handler(0xfa, interrupt_250_asm_entry); + register_interrupt_handler(0xfb, interrupt_251_asm_entry); + register_interrupt_handler(0xfc, interrupt_252_asm_entry); + register_interrupt_handler(0xfd, interrupt_253_asm_entry); + register_interrupt_handler(0xfe, interrupt_254_asm_entry); + register_interrupt_handler(0xff, interrupt_255_asm_entry); dbg() << "Installing Unhandled Handlers"; @@ -688,6 +738,8 @@ FPUState Processor::s_clean_fpu_state; static Vector<Processor*>* s_processors; static SpinLock s_processor_lock; +volatile u32 Processor::g_total_processors; +static volatile bool s_smp_enabled; Vector<Processor*>& Processor::processors() { @@ -707,6 +759,12 @@ Processor& Processor::by_id(u32 cpu) return *procs[cpu]; } +[[noreturn]] static inline void halt_this() +{ + for (;;) { + asm volatile("cli; hlt"); + } +} void Processor::cpu_detect() { @@ -868,13 +926,21 @@ void Processor::early_initialize(u32 cpu) m_invoke_scheduler_async = false; m_scheduler_initialized = false; + m_message_queue = nullptr; m_idle_thread = nullptr; m_current_thread = nullptr; m_mm_data = nullptr; m_info = nullptr; - cpu_setup(); + m_halt_requested = false; + if (cpu == 0) { + s_smp_enabled = false; + atomic_store(&g_total_processors, 1u, AK::MemoryOrder::memory_order_release); + } else { + atomic_fetch_add(&g_total_processors, 1u, AK::MemoryOrder::memory_order_acq_rel); + } + cpu_setup(); gdt_init(); ASSERT(¤t() == this); // sanity check } @@ -910,9 +976,9 @@ void Processor::initialize(u32 cpu) if (cpu >= s_processors->size()) s_processors->resize(cpu + 1); (*s_processors)[cpu] = this; - } - klog() << "CPU[" << cpu << "]: initialized Processor at " << VirtualAddress(FlatPtr(this)); + klog() << "CPU[" << cpu << "]: initialized Processor at " << VirtualAddress(FlatPtr(this)); + } } void Processor::write_raw_gdt_entry(u16 selector, u32 low, u32 high) @@ -979,7 +1045,7 @@ bool Processor::get_context_frame_ptr(Thread& thread, u32& frame_ptr, u32& eip) // TODO: If this is the case, the thread is currently running // on another processor. We can't trust the kernel stack as // it may be changing at any time. We need to probably send - // an ICI to that processor, have it walk the stack and wait + // an IPI to that processor, have it walk the stack and wait // until it returns the data back to us dbg() << "CPU[" << proc.id() << "] getting stack for " << thread << " on other CPU# " << thread.cpu() << " not yet implemented!"; @@ -1288,12 +1354,16 @@ void Processor::initialize_context_switching(Thread& initial_thread) "addl $20, %%ebx \n" // calculate pointer to TrapFrame "pushl %%ebx \n" "cld \n" + "pushl %[cpu] \n" + "call init_finished \n" + "addl $4, %%esp \n" "call enter_trap_no_irq \n" "addl $4, %%esp \n" "lret \n" :: [new_esp] "g" (tss.esp), [new_eip] "a" (tss.eip), - [from_to_thread] "b" (&initial_thread) + [from_to_thread] "b" (&initial_thread), + [cpu] "c" (id()) ); ASSERT_NOT_REACHED(); @@ -1312,7 +1382,9 @@ void Processor::exit_trap(TrapFrame& trap) InterruptDisabler disabler; ASSERT(m_in_irq >= trap.prev_irq_level); m_in_irq = trap.prev_irq_level; - + + smp_process_pending_messages(); + if (!m_in_irq && !m_in_critical) check_invoke_scheduler(); } @@ -1327,6 +1399,267 @@ void Processor::check_invoke_scheduler() } } +void Processor::flush_tlb_local(VirtualAddress vaddr, size_t page_count) +{ + auto ptr = vaddr.as_ptr(); + while (page_count > 0) { + asm volatile("invlpg %0" + : + : "m"(*(char*)vaddr.get()) + : "memory"); + ptr += PAGE_SIZE; + page_count--; + } +} + +void Processor::flush_tlb(VirtualAddress vaddr, size_t page_count) +{ + flush_tlb_local(vaddr, page_count); + if (s_smp_enabled) + smp_broadcast_flush_tlb(vaddr, page_count); +} + +static volatile ProcessorMessage* s_message_pool; + +void Processor::smp_return_to_pool(ProcessorMessage& msg) +{ + ProcessorMessage* next = nullptr; + do { + msg.next = next; + } while (!atomic_compare_exchange_strong(&s_message_pool, next, &msg, AK::MemoryOrder::memory_order_acq_rel)); +} + +ProcessorMessage& Processor::smp_get_from_pool() +{ + ProcessorMessage* msg; + + // The assumption is that messages are never removed from the pool! + for (;;) { + msg = atomic_load(&s_message_pool, AK::MemoryOrder::memory_order_consume); + if (!msg) { + if (!Processor::current().smp_process_pending_messages()) { + // TODO: pause for a bit? + } + continue; + } + // If another processor were to use this message in the meanwhile, + // "msg" is still valid (because it never gets freed). We'd detect + // this because the expected value "msg" and pool would + // no longer match, and the compare_exchange will fail. But accessing + // "msg->next" is always safe here. + if (atomic_compare_exchange_strong(&s_message_pool, msg, msg->next, AK::MemoryOrder::memory_order_acq_rel)) { + // We successfully "popped" this available message + break; + } + } + + ASSERT(msg != nullptr); + return *msg; +} + +void Processor::smp_enable() +{ + size_t msg_pool_size = Processor::count() * 100u; + size_t msg_entries_cnt = Processor::count(); + + auto msgs = new ProcessorMessage[msg_pool_size]; + auto msg_entries = new ProcessorMessageEntry[msg_pool_size * msg_entries_cnt]; + size_t msg_entry_i = 0; + for (size_t i = 0; i < msg_pool_size; i++, msg_entry_i += msg_entries_cnt) { + auto& msg = msgs[i]; + msg.next = i < msg_pool_size - 1 ? &msgs[i + 1] : nullptr; + msg.per_proc_entries = &msg_entries[msg_entry_i]; + for (size_t k = 0; k < msg_entries_cnt; k++) + msg_entries[msg_entry_i + k].msg = &msg; + } + + atomic_store(&s_message_pool, &msgs[0], AK::MemoryOrder::memory_order_release); + + // Start sending IPI messages + s_smp_enabled = true; +} + +void Processor::smp_cleanup_message(ProcessorMessage& msg) +{ + switch (msg.type) { + case ProcessorMessage::CallbackWithData: + if (msg.callback_with_data.free) + msg.callback_with_data.free(msg.callback_with_data.data); + break; + default: + break; + } +} + +bool Processor::smp_process_pending_messages() +{ + bool did_process = false; + u32 prev_flags; + enter_critical(prev_flags); + + if (auto pending_msgs = atomic_exchange(&m_message_queue, nullptr, AK::MemoryOrder::memory_order_acq_rel)) + { + // We pulled the stack of pending messages in LIFO order, so we need to reverse the list first + auto reverse_list = + [](ProcessorMessageEntry* list) -> ProcessorMessageEntry* + { + ProcessorMessageEntry* rev_list = nullptr; + while (list) { + auto next = list->next; + list->next = rev_list; + rev_list = list; + list = next; + } + return rev_list; + }; + + pending_msgs = reverse_list(pending_msgs); + + // now process in the right order + ProcessorMessageEntry* next_msg; + for (auto cur_msg = pending_msgs; cur_msg; cur_msg = next_msg) { + next_msg = cur_msg->next; + auto msg = cur_msg->msg; + +#ifdef SMP_DEBUG + dbg() << "SMP[" << id() << "]: Processing message " << VirtualAddress(msg); +#endif + + switch (msg->type) { + case ProcessorMessage::Callback: + msg->callback.handler(); + break; + case ProcessorMessage::CallbackWithData: + msg->callback_with_data.handler(msg->callback_with_data.data); + break; + case ProcessorMessage::FlushTlb: + flush_tlb_local(VirtualAddress(msg->flush_tlb.ptr), msg->flush_tlb.page_count); + break; + } + + bool is_async = msg->async; // Need to cache this value *before* dropping the ref count! + auto prev_refs = atomic_fetch_sub(&msg->refs, 1u, AK::MemoryOrder::memory_order_acq_rel); + ASSERT(prev_refs != 0); + if (prev_refs == 1) { + // All processors handled this. If this is an async message, + // we need to clean it up and return it to the pool + if (is_async) { + smp_cleanup_message(*msg); + smp_return_to_pool(*msg); + } + } + + if (m_halt_requested) + halt_this(); + } + did_process = true; + } else if (m_halt_requested) { + halt_this(); + } + + leave_critical(prev_flags); + return did_process; +} + +bool Processor::smp_queue_message(ProcessorMessage& msg) +{ + // Note that it's quite possible that the other processor may pop + // the queue at any given time. We rely on the fact that the messages + // are pooled and never get freed! + auto& msg_entry = msg.per_proc_entries[id()]; + ASSERT(msg_entry.msg == &msg); + ProcessorMessageEntry* next = nullptr; + do { + msg_entry.next = next; + } while (!atomic_compare_exchange_strong(&m_message_queue, next, &msg_entry, AK::MemoryOrder::memory_order_acq_rel)); + return next == nullptr; +} + +void Processor::smp_broadcast_message(ProcessorMessage& msg, bool async) +{ + auto& cur_proc = Processor::current(); + msg.async = async; +#ifdef SMP_DEBUG + dbg() << "SMP[" << cur_proc.id() << "]: Broadcast message " << VirtualAddress(&msg) << " to cpus: " << (count()) << " proc: " << VirtualAddress(&cur_proc); +#endif + atomic_store(&msg.refs, count() - 1, AK::MemoryOrder::memory_order_release); + ASSERT(msg.refs > 0); + for_each( + [&](Processor& proc) -> IterationDecision + { + if (&proc != &cur_proc) { + if (proc.smp_queue_message(msg)) { + // TODO: only send IPI to that CPU if we queued the first + } + } + return IterationDecision::Continue; + }); + + // Now trigger an IPI on all other APs + APIC::the().broadcast_ipi(); + + if (!async) { + // If synchronous then we must cleanup and return the message back + // to the pool. Otherwise, the last processor to complete it will return it + while (atomic_load(&msg.refs, AK::MemoryOrder::memory_order_consume) != 0) { + // TODO: pause for a bit? + } + + smp_cleanup_message(msg); + smp_return_to_pool(msg); + } +} + +void Processor::smp_broadcast(void(*callback)(void*), void* data, void(*free_data)(void*), bool async) +{ + auto& msg = smp_get_from_pool(); + msg.type = ProcessorMessage::CallbackWithData; + msg.callback_with_data.handler = callback; + msg.callback_with_data.data = data; + msg.callback_with_data.free = free_data; + smp_broadcast_message(msg, async); +} + +void Processor::smp_broadcast(void(*callback)(), bool async) +{ + auto& msg = smp_get_from_pool(); + msg.type = ProcessorMessage::CallbackWithData; + msg.callback.handler = callback; + smp_broadcast_message(msg, async); +} + +void Processor::smp_broadcast_flush_tlb(VirtualAddress vaddr, size_t page_count) +{ + auto& msg = smp_get_from_pool(); + msg.type = ProcessorMessage::FlushTlb; + msg.flush_tlb.ptr = vaddr.as_ptr(); + msg.flush_tlb.page_count = page_count; + smp_broadcast_message(msg, false); +} + +void Processor::smp_broadcast_halt() +{ + // We don't want to use a message, because this could have been triggered + // by being out of memory and we might not be able to get a message + for_each( + [&](Processor& proc) -> IterationDecision + { + proc.m_halt_requested = true; + return IterationDecision::Continue; + }); + + // Now trigger an IPI on all other APs + APIC::the().broadcast_ipi(); +} + +void Processor::Processor::halt() +{ + if (s_smp_enabled) + smp_broadcast_halt(); + + halt_this(); +} + void Processor::gdt_init() { m_gdt_length = 0; diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index 1c53a48660..60f92e6786 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -26,6 +26,7 @@ #pragma once +#include <AK/Atomic.h> #include <AK/Badge.h> #include <AK/Noncopyable.h> #include <AK/Vector.h> @@ -33,7 +34,7 @@ #include <Kernel/VirtualAddress.h> #define PAGE_SIZE 4096 -#define GENERIC_INTERRUPT_HANDLERS_COUNT 128 +#define GENERIC_INTERRUPT_HANDLERS_COUNT (256 - IRQ_VECTOR_BASE) #define PAGE_MASK ((FlatPtr)0xfffff000u) namespace Kernel { @@ -276,13 +277,6 @@ void flush_idt(); void load_task_register(u16 selector); void handle_crash(RegisterState&, const char* description, int signal, bool out_of_memory = false); -[[noreturn]] static inline void hang() -{ - asm volatile("cli; hlt"); - for (;;) { - } -} - #define LSW(x) ((u32)(x)&0xFFFF) #define MSW(x) (((u32)(x) >> 16) & 0xFFFF) #define LSB(x) ((x)&0xFF) @@ -307,20 +301,17 @@ inline u32 cpu_flags() inline void set_fs(u32 segment) { asm volatile( - "movl %%eax, %%fs" :: "a"(segment) - : "memory" - ); + "movl %%eax, %%fs" ::"a"(segment) + : "memory"); } inline void set_gs(u32 segment) { asm volatile( - "movl %%eax, %%gs" :: "a"(segment) - : "memory" - ); + "movl %%eax, %%gs" ::"a"(segment) + : "memory"); } - inline u32 get_fs() { u32 fs; @@ -532,9 +523,9 @@ u32 read_dr6(); static inline bool is_kernel_mode() { u32 cs; - asm volatile ( + asm volatile( "movl %%cs, %[cs] \n" - : [cs] "=g" (cs)); + : [ cs ] "=g"(cs)); return (cs & 3) == 0; } @@ -624,10 +615,48 @@ struct TrapFrame; class ProcessorInfo; struct MemoryManagerData; +struct ProcessorMessageEntry; + +struct ProcessorMessage { + enum Type { + FlushTlb, + Callback, + CallbackWithData + }; + Type type; + volatile u32 refs; // atomic + union { + ProcessorMessage* next; // only valid while in the pool + struct { + void (*handler)(); + } callback; + struct { + void* data; + void (*handler)(void*); + void (*free)(void*); + } callback_with_data; + struct { + u8* ptr; + size_t page_count; + } flush_tlb; + }; + + volatile bool async; + + ProcessorMessageEntry* per_proc_entries; +}; + +struct ProcessorMessageEntry { + ProcessorMessageEntry* next; + ProcessorMessage* msg; +}; class Processor { friend class ProcessorInfo; + AK_MAKE_NONCOPYABLE(Processor); + AK_MAKE_NONMOVABLE(Processor); + Processor* m_self; // must be first field (%fs offset 0x0) DescriptorTablePointer m_gdtr; @@ -641,48 +670,85 @@ class Processor { TSS32 m_tss; static FPUState s_clean_fpu_state; CPUFeature m_features; + static volatile u32 g_total_processors; // atomic ProcessorInfo* m_info; MemoryManagerData* m_mm_data; Thread* m_current_thread; Thread* m_idle_thread; + volatile ProcessorMessageEntry* m_message_queue; // atomic, LIFO + bool m_invoke_scheduler_async; bool m_scheduler_initialized; + bool m_halt_requested; void gdt_init(); void write_raw_gdt_entry(u16 selector, u32 low, u32 high); void write_gdt_entry(u16 selector, Descriptor& descriptor); static Vector<Processor*>& processors(); + static void smp_return_to_pool(ProcessorMessage& msg); + static ProcessorMessage& smp_get_from_pool(); + static void smp_cleanup_message(ProcessorMessage& msg); + bool smp_queue_message(ProcessorMessage& msg); + static void smp_broadcast_message(ProcessorMessage& msg, bool async); + static void smp_broadcast_halt(); + void cpu_detect(); void cpu_setup(); String features_string() const; public: + Processor() = default; + void early_initialize(u32 cpu); void initialize(u32 cpu); + static u32 count() + { + // NOTE: because this value never changes once all APs are booted, + // we don't really need to do an atomic_load() on this variable + return g_total_processors; + } + + ALWAYS_INLINE static void wait_check() + { + Processor::current().smp_process_pending_messages(); + // TODO: pause + } + + [[noreturn]] static void halt(); + + static void flush_entire_tlb_local() + { + write_cr3(read_cr3()); + } + + static void flush_tlb_local(VirtualAddress vaddr, size_t page_count); + static void flush_tlb(VirtualAddress vaddr, size_t page_count); + Descriptor& get_gdt_entry(u16 selector); void flush_gdt(); const DescriptorTablePointer& get_gdtr(); static Processor& by_id(u32 cpu); - template <typename Callback> + template<typename Callback> static inline IterationDecision for_each(Callback callback) { auto& procs = processors(); - for (auto it = procs.begin(); it != procs.end(); ++it) { - if (callback(**it) == IterationDecision::Break) + size_t count = procs.size(); + for (size_t i = 0; i < count; i++) { + if (callback(*procs[i]) == IterationDecision::Break) return IterationDecision::Break; } return IterationDecision::Continue; } - + ALWAYS_INLINE ProcessorInfo& info() { return *m_info; } - + ALWAYS_INLINE static Processor& current() { return *(Processor*)read_fs_u32(0); @@ -729,19 +795,30 @@ public: { return m_cpu; } - + + ALWAYS_INLINE u32 raise_irq() + { + return m_in_irq++; + } + + ALWAYS_INLINE void restore_irq(u32 prev_irq) + { + ASSERT(prev_irq <= m_in_irq); + m_in_irq = prev_irq; + } + ALWAYS_INLINE u32& in_irq() { return m_in_irq; } - + ALWAYS_INLINE void enter_critical(u32& prev_flags) { m_in_critical++; prev_flags = cpu_flags(); cli(); } - + ALWAYS_INLINE void leave_critical(u32 prev_flags) { ASSERT(m_in_critical > 0); @@ -754,7 +831,7 @@ public: else cli(); } - + ALWAYS_INLINE u32 clear_critical(u32& prev_flags, bool enable_interrupts) { u32 prev_crit = m_in_critical; @@ -766,7 +843,7 @@ public: sti(); return prev_crit; } - + ALWAYS_INLINE void restore_critical(u32 prev_crit, u32 prev_flags) { ASSERT(m_in_critical == 0); @@ -784,6 +861,27 @@ public: return s_clean_fpu_state; } + static void smp_enable(); + bool smp_process_pending_messages(); + + template<typename Callback> + static void smp_broadcast(Callback callback, bool async) + { + auto* data = new Callback(move(callback)); + smp_broadcast( + [](void* data) { + (*reinterpret_cast<Callback*>(data))(); + }, + data, + [](void* data) { + delete reinterpret_cast<Callback*>(data); + }, + async); + } + static void smp_broadcast(void (*callback)(), bool async); + static void smp_broadcast(void (*callback)(void*), void* data, void (*free_data)(void*), bool async); + static void smp_broadcast_flush_tlb(VirtualAddress vaddr, size_t page_count); + ALWAYS_INLINE bool has_feature(CPUFeature f) const { return (static_cast<u32>(m_features) & static_cast<u32>(f)) != 0; @@ -793,6 +891,7 @@ public: void invoke_scheduler_async() { m_invoke_scheduler_async = true; } void enter_trap(TrapFrame& trap, bool raise_irq); + void exit_trap(TrapFrame& trap); [[noreturn]] void initialize_context_switching(Thread& initial_thread); diff --git a/Kernel/Arch/i386/ISRStubs.h b/Kernel/Arch/i386/ISRStubs.h index af5e6cf521..86db4644a1 100644 --- a/Kernel/Arch/i386/ISRStubs.h +++ b/Kernel/Arch/i386/ISRStubs.h @@ -28,260 +28,179 @@ #include <Kernel/Arch/i386/Interrupts.h> -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(0, 0x50) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(1, 0x51) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(2, 0x52) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(3, 0x53) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(4, 0x54) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(5, 0x55) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(6, 0x56) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(7, 0x57) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(8, 0x58) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(9, 0x59) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(10, 0x5a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(11, 0x5b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(12, 0x5c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(13, 0x5d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(14, 0x5e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(15, 0x5f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(16, 0x60) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(17, 0x61) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(18, 0x62) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(19, 0x63) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(20, 0x64) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(21, 0x65) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(22, 0x66) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(23, 0x67) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(24, 0x68) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(25, 0x69) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(26, 0x6a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(27, 0x6b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(28, 0x6c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(29, 0x6d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(30, 0x6e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(31, 0x6f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(32, 0x70) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(33, 0x71) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(34, 0x72) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(35, 0x73) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(36, 0x74) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(37, 0x75) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(38, 0x76) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(39, 0x77) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(40, 0x78) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(41, 0x79) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(42, 0x7a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(43, 0x7b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(44, 0x7c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(45, 0x7d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(46, 0x7e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(47, 0x7f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(48, 0x80) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(49, 0x81) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(50, 0x82) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(51, 0x83) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(52, 0x84) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(53, 0x85) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(54, 0x86) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(55, 0x87) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(56, 0x88) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(57, 0x89) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(58, 0x8a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(59, 0x8b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(60, 0x8c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(61, 0x8d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(62, 0x8e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(63, 0x8f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(64, 0x90) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(65, 0x91) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(66, 0x92) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(67, 0x93) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(68, 0x94) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(69, 0x95) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(70, 0x96) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(71, 0x97) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(72, 0x98) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(73, 0x99) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(74, 0x9a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(75, 0x9b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(76, 0x9c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(77, 0x9d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(78, 0x9e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(79, 0x9f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(80, 0xa0) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(81, 0xa1) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(82, 0xa2) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(83, 0xa3) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(84, 0xa4) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(85, 0xa5) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(86, 0xa6) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(87, 0xa7) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(88, 0xa8) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(89, 0xa9) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(90, 0xaa) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(91, 0xab) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(92, 0xac) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(93, 0xad) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(94, 0xae) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(95, 0xaf) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(96, 0xb0) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(97, 0xb1) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(98, 0xb2) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(99, 0xb3) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(100, 0xb4) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(101, 0xb5) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(102, 0xb6) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(103, 0xb7) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(104, 0xb8) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(105, 0xb9) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(106, 0xba) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(107, 0xbb) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(108, 0xbc) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(109, 0xbd) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(110, 0xbe) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(111, 0xbf) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(112, 0xc0) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(113, 0xc1) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(114, 0xc2) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(115, 0xc3) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(116, 0xc4) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(117, 0xc5) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(118, 0xc6) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(119, 0xc7) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(120, 0xc8) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(121, 0xc9) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(122, 0xca) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(123, 0xcb) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(124, 0xcc) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(125, 0xcd) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(126, 0xce) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(127, 0xcf) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(128, 0xd0) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(129, 0xd1) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(130, 0xd2) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(131, 0xd3) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(132, 0xd4) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(133, 0xd5) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(134, 0xd6) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(135, 0xd7) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(136, 0xd8) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(137, 0xd9) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(138, 0xda) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(139, 0xdb) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(140, 0xdc) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(141, 0xdd) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(142, 0xde) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(143, 0xdf) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(144, 0xe0) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(145, 0xe1) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(146, 0xe2) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(147, 0xe3) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(148, 0xe4) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(149, 0xe5) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(150, 0xe6) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(151, 0xe7) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(152, 0xe8) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(153, 0xe9) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(154, 0xea) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(155, 0xeb) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(156, 0xec) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(157, 0xed) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(158, 0xee) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(159, 0xef) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(160, 0xf0) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(161, 0xf1) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(162, 0xf2) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(163, 0xf3) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(164, 0xf4) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(165, 0xf5) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(166, 0xf6) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(167, 0xf7) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(168, 0xf8) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(169, 0xf9) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(170, 0xfa) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(171, 0xfb) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(172, 0xfc) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(173, 0xfd) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(174, 0xfe) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(175, 0xff) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(176, 0x100) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(177, 0x101) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(178, 0x102) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(179, 0x103) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(180, 0x104) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(181, 0x105) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(182, 0x106) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(183, 0x107) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(184, 0x108) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(185, 0x109) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(186, 0x10a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(187, 0x10b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(188, 0x10c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(189, 0x10d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(190, 0x10e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(191, 0x10f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(192, 0x110) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(193, 0x111) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(194, 0x112) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(195, 0x113) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(196, 0x114) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(197, 0x115) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(198, 0x116) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(199, 0x117) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(200, 0x118) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(201, 0x119) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(202, 0x11a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(203, 0x11b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(204, 0x11c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(205, 0x11d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(206, 0x11e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(207, 0x11f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(208, 0x120) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(209, 0x121) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(210, 0x122) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(211, 0x123) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(212, 0x124) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(213, 0x125) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(214, 0x126) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(215, 0x127) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(216, 0x128) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(217, 0x129) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(218, 0x12a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(219, 0x12b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(220, 0x12c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(221, 0x12d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(222, 0x12e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(223, 0x12f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(224, 0x130) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(225, 0x131) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(226, 0x132) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(227, 0x133) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(228, 0x134) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(229, 0x135) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(230, 0x136) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(231, 0x137) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(232, 0x138) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(233, 0x139) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(234, 0x13a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(235, 0x13b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(236, 0x13c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(237, 0x13d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(238, 0x13e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(239, 0x13f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(240, 0x140) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(241, 0x141) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(242, 0x142) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(243, 0x143) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(244, 0x144) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(245, 0x145) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(246, 0x146) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(247, 0x147) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(248, 0x148) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(249, 0x149) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(250, 0x14a) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(251, 0x14b) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(252, 0x14c) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(253, 0x14d) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(254, 0x14e) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(255, 0x14f) -GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(256, 0x150) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(80) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(81) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(82) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(83) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(84) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(85) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(86) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(87) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(88) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(89) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(90) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(91) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(92) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(93) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(94) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(95) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(96) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(97) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(98) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(99) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(100) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(101) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(102) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(103) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(104) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(105) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(106) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(107) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(108) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(109) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(110) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(111) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(112) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(113) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(114) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(115) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(116) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(117) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(118) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(119) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(120) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(121) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(122) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(123) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(124) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(125) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(126) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(127) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(128) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(129) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(130) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(131) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(132) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(133) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(134) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(135) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(136) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(137) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(138) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(139) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(140) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(141) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(142) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(143) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(144) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(145) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(146) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(147) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(148) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(149) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(150) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(151) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(152) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(153) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(154) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(155) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(156) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(157) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(158) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(159) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(160) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(161) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(162) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(163) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(164) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(165) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(166) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(167) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(168) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(169) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(170) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(171) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(172) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(173) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(174) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(175) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(176) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(177) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(178) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(179) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(180) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(181) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(182) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(183) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(184) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(185) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(186) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(187) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(188) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(189) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(190) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(191) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(192) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(193) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(194) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(195) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(196) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(197) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(198) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(199) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(200) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(201) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(202) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(203) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(204) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(205) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(206) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(207) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(208) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(209) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(210) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(211) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(212) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(213) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(214) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(215) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(216) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(217) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(218) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(219) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(220) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(221) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(222) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(223) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(224) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(225) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(226) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(227) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(228) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(229) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(230) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(231) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(232) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(233) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(234) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(235) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(236) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(237) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(238) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(239) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(240) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(241) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(242) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(243) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(244) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(245) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(246) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(247) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(248) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(249) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(250) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(251) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(252) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(253) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(254) +GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(255) diff --git a/Kernel/Arch/i386/Interrupts.h b/Kernel/Arch/i386/Interrupts.h index c209f95d8f..320e26281e 100644 --- a/Kernel/Arch/i386/Interrupts.h +++ b/Kernel/Arch/i386/Interrupts.h @@ -32,12 +32,12 @@ extern "C" void interrupt_common_asm_entry(); -#define GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(interrupt_vector, isr_number) \ - extern "C" void interrupt_##interrupt_vector##_asm_entry(); \ - asm(".globl interrupt_" #interrupt_vector "_asm_entry\n" \ - "interrupt_" #interrupt_vector "_asm_entry:\n" \ - " pushw $" #isr_number "\n" \ - " pushw $0\n" \ +#define GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(isr_number) \ + extern "C" void interrupt_##isr_number##_asm_entry(); \ + asm(".globl interrupt_" #isr_number "_asm_entry\n" \ + "interrupt_" #isr_number "_asm_entry:\n" \ + " pushw $" #isr_number "\n" \ + " pushw $0\n" \ " jmp interrupt_common_asm_entry\n"); asm( diff --git a/Kernel/Arch/i386/ProcessorInfo.h b/Kernel/Arch/i386/ProcessorInfo.h index 2ea9a19dbe..c74d74e607 100644 --- a/Kernel/Arch/i386/ProcessorInfo.h +++ b/Kernel/Arch/i386/ProcessorInfo.h @@ -42,6 +42,7 @@ class ProcessorInfo u32 m_display_family; u32 m_stepping; u32 m_type; + u32 m_apic_id; public: ProcessorInfo(Processor& processor); @@ -53,6 +54,9 @@ public: u32 display_family() const { return m_display_family; } u32 stepping() const { return m_stepping; } u32 type() const { return m_type; } + u32 apic_id() const { return m_apic_id; } + + void set_apic_id(u32 apic_id) { m_apic_id = apic_id; } }; } |