CPU.cpp 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <AK/Assertions.h>
  27. #include <AK/String.h>
  28. #include <AK/StringBuilder.h>
  29. #include <AK/Types.h>
  30. #include <Kernel/Arch/i386/CPU.h>
  31. #include <Kernel/Arch/i386/ProcessorInfo.h>
  32. #include <Kernel/Arch/i386/ISRStubs.h>
  33. #include <Kernel/Interrupts/APIC.h>
  34. #include <Kernel/Interrupts/GenericInterruptHandler.h>
  35. #include <Kernel/Interrupts/IRQHandler.h>
  36. #include <Kernel/Interrupts/InterruptManagement.h>
  37. #include <Kernel/Interrupts/SharedIRQHandler.h>
  38. #include <Kernel/Interrupts/SpuriousInterruptHandler.h>
  39. #include <Kernel/Interrupts/UnhandledInterruptHandler.h>
  40. #include <Kernel/KSyms.h>
  41. #include <Kernel/Process.h>
  42. #include <Kernel/SpinLock.h>
  43. #include <Kernel/Thread.h>
  44. #include <Kernel/VM/MemoryManager.h>
  45. #include <Kernel/VM/PageDirectory.h>
  46. #include <Kernel/IO.h>
  47. #include <LibC/mallocdefs.h>
  48. //#define PAGE_FAULT_DEBUG
  49. //#define CONTEXT_SWITCH_DEBUG
  50. namespace Kernel {
  51. static DescriptorTablePointer s_idtr;
  52. static Descriptor s_idt[256];
  53. static GenericInterruptHandler* s_interrupt_handler[GENERIC_INTERRUPT_HANDLERS_COUNT];
  54. extern "C" void handle_interrupt(TrapFrame*);
  55. #define EH_ENTRY(ec, title) \
  56. extern "C" void title##_asm_entry(); \
  57. extern "C" void title##_handler(TrapFrame*); \
  58. asm( \
  59. ".globl " #title "_asm_entry\n" \
  60. "" #title "_asm_entry: \n" \
  61. " pusha\n" \
  62. " pushl %ds\n" \
  63. " pushl %es\n" \
  64. " pushl %fs\n" \
  65. " pushl %gs\n" \
  66. " pushl %ss\n" \
  67. " mov $" __STRINGIFY(GDT_SELECTOR_DATA0) ", %ax\n" \
  68. " mov %ax, %ds\n" \
  69. " mov %ax, %es\n" \
  70. " mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n" \
  71. " mov %ax, %fs\n" \
  72. " pushl %esp \n" /* set TrapFrame::regs */ \
  73. " subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n" \
  74. " pushl %esp \n" \
  75. " cld\n" \
  76. " call enter_trap_no_irq \n" \
  77. " call " #title "_handler\n" \
  78. " jmp common_trap_exit \n");
  79. #define EH_ENTRY_NO_CODE(ec, title) \
  80. extern "C" void title##_handler(TrapFrame*); \
  81. extern "C" void title##_asm_entry(); \
  82. asm( \
  83. ".globl " #title "_asm_entry\n" \
  84. "" #title "_asm_entry: \n" \
  85. " pushl $0x0\n" \
  86. " pusha\n" \
  87. " pushl %ds\n" \
  88. " pushl %es\n" \
  89. " pushl %fs\n" \
  90. " pushl %gs\n" \
  91. " pushl %ss\n" \
  92. " mov $" __STRINGIFY(GDT_SELECTOR_DATA0) ", %ax\n" \
  93. " mov %ax, %ds\n" \
  94. " mov %ax, %es\n" \
  95. " mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n" \
  96. " mov %ax, %fs\n" \
  97. " pushl %esp \n" /* set TrapFrame::regs */ \
  98. " subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n" \
  99. " pushl %esp \n" \
  100. " cld\n" \
  101. " call enter_trap_no_irq \n" \
  102. " call " #title "_handler\n" \
  103. " jmp common_trap_exit \n");
  104. static void dump(const RegisterState& regs)
  105. {
  106. u16 ss;
  107. u32 esp;
  108. auto process = Process::current();
  109. if (!process || process->is_ring0()) {
  110. ss = regs.ss;
  111. esp = regs.esp;
  112. } else {
  113. ss = regs.userspace_ss;
  114. esp = regs.userspace_esp;
  115. }
  116. klog() << "exception code: " << String::format("%04x", regs.exception_code) << " (isr: " << String::format("%04x", regs.isr_number);
  117. klog() << " pc=" << String::format("%04x", (u16)regs.cs) << ":" << String::format("%08x", regs.eip) << " flags=" << String::format("%04x", (u16)regs.eflags);
  118. klog() << " stk=" << String::format("%04x", ss) << ":" << String::format("%08x", esp);
  119. klog() << " ds=" << String::format("%04x", (u16)regs.ds) << " es=" << String::format("%04x", (u16)regs.es) << " fs=" << String::format("%04x", (u16)regs.fs) << " gs=" << String::format("%04x", (u16)regs.gs);
  120. klog() << "eax=" << String::format("%08x", regs.eax) << " ebx=" << String::format("%08x", regs.ebx) << " ecx=" << String::format("%08x", regs.ecx) << " edx=" << String::format("%08x", regs.edx);
  121. klog() << "ebp=" << String::format("%08x", regs.ebp) << " esp=" << String::format("%08x", regs.esp) << " esi=" << String::format("%08x", regs.esi) << " edi=" << String::format("%08x", regs.edi);
  122. u32 cr0;
  123. asm("movl %%cr0, %%eax"
  124. : "=a"(cr0));
  125. u32 cr2;
  126. asm("movl %%cr2, %%eax"
  127. : "=a"(cr2));
  128. u32 cr3 = read_cr3();
  129. u32 cr4;
  130. asm("movl %%cr4, %%eax"
  131. : "=a"(cr4));
  132. klog() << "cr0=" << String::format("%08x", cr0) << " cr2=" << String::format("%08x", cr2) << " cr3=" << String::format("%08x", cr3) << " cr4=" << String::format("%08x", cr4);
  133. if (process && process->validate_read((void*)regs.eip, 8)) {
  134. SmapDisabler disabler;
  135. u8* codeptr = (u8*)regs.eip;
  136. klog() << "code: " << String::format("%02x", codeptr[0]) << " " << String::format("%02x", codeptr[1]) << " " << String::format("%02x", codeptr[2]) << " " << String::format("%02x", codeptr[3]) << " " << String::format("%02x", codeptr[4]) << " " << String::format("%02x", codeptr[5]) << " " << String::format("%02x", codeptr[6]) << " " << String::format("%02x", codeptr[7]);
  137. }
  138. }
  139. void handle_crash(RegisterState& regs, const char* description, int signal, bool out_of_memory)
  140. {
  141. auto process = Process::current();
  142. if (!process) {
  143. klog() << description << " with !current";
  144. hang();
  145. }
  146. // If a process crashed while inspecting another process,
  147. // make sure we switch back to the right page tables.
  148. MM.enter_process_paging_scope(*process);
  149. klog() << "CRASH: CPU #" << Processor::current().id() << " " << description << ". Ring " << (process->is_ring0() ? 0 : 3) << ".";
  150. dump(regs);
  151. if (process->is_ring0()) {
  152. klog() << "Crash in ring 0 :(";
  153. dump_backtrace();
  154. hang();
  155. }
  156. cli();
  157. process->crash(signal, regs.eip, out_of_memory);
  158. }
  159. EH_ENTRY_NO_CODE(6, illegal_instruction);
  160. void illegal_instruction_handler(TrapFrame* trap)
  161. {
  162. clac();
  163. handle_crash(*trap->regs, "Illegal instruction", SIGILL);
  164. }
  165. EH_ENTRY_NO_CODE(0, divide_error);
  166. void divide_error_handler(TrapFrame* trap)
  167. {
  168. clac();
  169. handle_crash(*trap->regs, "Divide error", SIGFPE);
  170. }
  171. EH_ENTRY(13, general_protection_fault);
  172. void general_protection_fault_handler(TrapFrame* trap)
  173. {
  174. clac();
  175. handle_crash(*trap->regs, "General protection fault", SIGSEGV);
  176. }
  177. // 7: FPU not available exception
  178. EH_ENTRY_NO_CODE(7, fpu_exception);
  179. void fpu_exception_handler(TrapFrame*)
  180. {
  181. // Just clear the TS flag. We've already restored the FPU state eagerly.
  182. // FIXME: It would be nice if we didn't have to do this at all.
  183. asm volatile("clts");
  184. }
  185. // 14: Page Fault
  186. EH_ENTRY(14, page_fault);
  187. void page_fault_handler(TrapFrame* trap)
  188. {
  189. clac();
  190. auto& regs = *trap->regs;
  191. u32 fault_address;
  192. asm("movl %%cr2, %%eax"
  193. : "=a"(fault_address));
  194. #ifdef PAGE_FAULT_DEBUG
  195. u32 fault_page_directory = read_cr3();
  196. dbg() << "CPU #" << (Processor::is_initialized() ? Processor::current().id() : 0) << " ring " << (regs.cs & 3)
  197. << " " << (regs.exception_code & 1 ? "PV" : "NP")
  198. << " page fault in PD=" << String::format("%x", fault_page_directory) << ", "
  199. << (regs.exception_code & 8 ? "reserved-bit " : "")
  200. << (regs.exception_code & 2 ? "write" : "read")
  201. << " " << VirtualAddress(fault_address);
  202. #endif
  203. #ifdef PAGE_FAULT_DEBUG
  204. dump(regs);
  205. #endif
  206. bool faulted_in_userspace = (regs.cs & 3) == 3;
  207. auto current_thread = Thread::current();
  208. if (faulted_in_userspace && !MM.validate_user_stack(current_thread->process(), VirtualAddress(regs.userspace_esp))) {
  209. dbg() << "Invalid stack pointer: " << VirtualAddress(regs.userspace_esp);
  210. handle_crash(regs, "Bad stack on page fault", SIGSTKFLT);
  211. ASSERT_NOT_REACHED();
  212. }
  213. auto response = MM.handle_page_fault(PageFault(regs.exception_code, VirtualAddress(fault_address)));
  214. if (response == PageFaultResponse::ShouldCrash || response == PageFaultResponse::OutOfMemory) {
  215. if (response != PageFaultResponse::OutOfMemory) {
  216. if (current_thread->has_signal_handler(SIGSEGV)) {
  217. current_thread->send_urgent_signal_to_self(SIGSEGV);
  218. return;
  219. }
  220. }
  221. dbg() << "Unrecoverable page fault, "
  222. << (regs.exception_code & PageFaultFlags::ReservedBitViolation ? "reserved bit violation / " : "")
  223. << (regs.exception_code & PageFaultFlags::InstructionFetch ? "instruction fetch / " : "")
  224. << (regs.exception_code & PageFaultFlags::Write ? "write to" : "read from")
  225. << " address " << VirtualAddress(fault_address);
  226. u32 malloc_scrub_pattern = explode_byte(MALLOC_SCRUB_BYTE);
  227. u32 free_scrub_pattern = explode_byte(FREE_SCRUB_BYTE);
  228. u32 kmalloc_scrub_pattern = explode_byte(KMALLOC_SCRUB_BYTE);
  229. u32 kfree_scrub_pattern = explode_byte(KFREE_SCRUB_BYTE);
  230. u32 slab_alloc_scrub_pattern = explode_byte(SLAB_ALLOC_SCRUB_BYTE);
  231. u32 slab_dealloc_scrub_pattern = explode_byte(SLAB_DEALLOC_SCRUB_BYTE);
  232. if ((fault_address & 0xffff0000) == (malloc_scrub_pattern & 0xffff0000)) {
  233. dbg() << "Note: Address " << VirtualAddress(fault_address) << " looks like it may be uninitialized malloc() memory";
  234. } else if ((fault_address & 0xffff0000) == (free_scrub_pattern & 0xffff0000)) {
  235. dbg() << "Note: Address " << VirtualAddress(fault_address) << " looks like it may be recently free()'d memory";
  236. } else if ((fault_address & 0xffff0000) == (kmalloc_scrub_pattern & 0xffff0000)) {
  237. dbg() << "Note: Address " << VirtualAddress(fault_address) << " looks like it may be uninitialized kmalloc() memory";
  238. } else if ((fault_address & 0xffff0000) == (kfree_scrub_pattern & 0xffff0000)) {
  239. dbg() << "Note: Address " << VirtualAddress(fault_address) << " looks like it may be recently kfree()'d memory";
  240. } else if ((fault_address & 0xffff0000) == (slab_alloc_scrub_pattern & 0xffff0000)) {
  241. dbg() << "Note: Address " << VirtualAddress(fault_address) << " looks like it may be uninitialized slab_alloc() memory";
  242. } else if ((fault_address & 0xffff0000) == (slab_dealloc_scrub_pattern & 0xffff0000)) {
  243. dbg() << "Note: Address " << VirtualAddress(fault_address) << " looks like it may be recently slab_dealloc()'d memory";
  244. } else if (fault_address < 4096) {
  245. dbg() << "Note: Address " << VirtualAddress(fault_address) << " looks like a possible nullptr dereference";
  246. }
  247. handle_crash(regs, "Page Fault", SIGSEGV, response == PageFaultResponse::OutOfMemory);
  248. } else if (response == PageFaultResponse::Continue) {
  249. #ifdef PAGE_FAULT_DEBUG
  250. dbg() << "Continuing after resolved page fault";
  251. #endif
  252. } else {
  253. ASSERT_NOT_REACHED();
  254. }
  255. }
  256. EH_ENTRY_NO_CODE(1, debug);
  257. void debug_handler(TrapFrame* trap)
  258. {
  259. clac();
  260. auto& regs = *trap->regs;
  261. auto current_thread = Thread::current();
  262. if (&current_thread->process() == nullptr || (regs.cs & 3) == 0) {
  263. klog() << "Debug Exception in Ring0";
  264. hang();
  265. return;
  266. }
  267. constexpr u8 REASON_SINGLESTEP = 14;
  268. bool is_reason_singlestep = (read_dr6() & (1 << REASON_SINGLESTEP));
  269. if (!is_reason_singlestep)
  270. return;
  271. if (current_thread->tracer()) {
  272. current_thread->tracer()->set_regs(regs);
  273. }
  274. current_thread->send_urgent_signal_to_self(SIGTRAP);
  275. }
  276. EH_ENTRY_NO_CODE(3, breakpoint);
  277. void breakpoint_handler(TrapFrame* trap)
  278. {
  279. clac();
  280. auto& regs = *trap->regs;
  281. auto current_thread = Thread::current();
  282. if (&current_thread->process() == nullptr || (regs.cs & 3) == 0) {
  283. klog() << "Breakpoint Trap in Ring0";
  284. hang();
  285. return;
  286. }
  287. if (current_thread->tracer()) {
  288. current_thread->tracer()->set_regs(regs);
  289. }
  290. current_thread->send_urgent_signal_to_self(SIGTRAP);
  291. }
  292. #define EH(i, msg) \
  293. static void _exception##i() \
  294. { \
  295. klog() << msg; \
  296. u32 cr0, cr2, cr3, cr4; \
  297. asm("movl %%cr0, %%eax" \
  298. : "=a"(cr0)); \
  299. asm("movl %%cr2, %%eax" \
  300. : "=a"(cr2)); \
  301. asm("movl %%cr3, %%eax" \
  302. : "=a"(cr3)); \
  303. asm("movl %%cr4, %%eax" \
  304. : "=a"(cr4)); \
  305. klog() << "CR0=" << String::format("%x", cr0) << " CR2=" << String::format("%x", cr2) << " CR3=" << String::format("%x", cr3) << " CR4=" << String::format("%x", cr4); \
  306. hang(); \
  307. }
  308. EH(2, "Unknown error")
  309. EH(4, "Overflow")
  310. EH(5, "Bounds check")
  311. EH(8, "Double fault")
  312. EH(9, "Coprocessor segment overrun")
  313. EH(10, "Invalid TSS")
  314. EH(11, "Segment not present")
  315. EH(12, "Stack exception")
  316. EH(15, "Unknown error")
  317. EH(16, "Coprocessor error")
  318. const DescriptorTablePointer& get_idtr()
  319. {
  320. return s_idtr;
  321. }
  322. static void unimp_trap()
  323. {
  324. klog() << "Unhandled IRQ.";
  325. hang();
  326. }
  327. GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number)
  328. {
  329. ASSERT(s_interrupt_handler[interrupt_number] != nullptr);
  330. return *s_interrupt_handler[interrupt_number];
  331. }
  332. static void revert_to_unused_handler(u8 interrupt_number)
  333. {
  334. new UnhandledInterruptHandler(interrupt_number);
  335. }
  336. void register_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
  337. {
  338. if (s_interrupt_handler[interrupt_number] != nullptr) {
  339. if (s_interrupt_handler[interrupt_number]->type() == HandlerType::UnhandledInterruptHandler) {
  340. s_interrupt_handler[interrupt_number] = &handler;
  341. return;
  342. }
  343. if (s_interrupt_handler[interrupt_number]->is_shared_handler() && !s_interrupt_handler[interrupt_number]->is_sharing_with_others()) {
  344. ASSERT(s_interrupt_handler[interrupt_number]->type() == HandlerType::SharedIRQHandler);
  345. static_cast<SharedIRQHandler*>(s_interrupt_handler[interrupt_number])->register_handler(handler);
  346. return;
  347. }
  348. if (!s_interrupt_handler[interrupt_number]->is_shared_handler()) {
  349. ASSERT(s_interrupt_handler[interrupt_number]->type() == HandlerType::IRQHandler);
  350. auto& previous_handler = *s_interrupt_handler[interrupt_number];
  351. s_interrupt_handler[interrupt_number] = nullptr;
  352. SharedIRQHandler::initialize(interrupt_number);
  353. static_cast<SharedIRQHandler*>(s_interrupt_handler[interrupt_number])->register_handler(previous_handler);
  354. static_cast<SharedIRQHandler*>(s_interrupt_handler[interrupt_number])->register_handler(handler);
  355. return;
  356. }
  357. ASSERT_NOT_REACHED();
  358. } else {
  359. s_interrupt_handler[interrupt_number] = &handler;
  360. }
  361. }
  362. void unregister_generic_interrupt_handler(u8 interrupt_number, GenericInterruptHandler& handler)
  363. {
  364. ASSERT(s_interrupt_handler[interrupt_number] != nullptr);
  365. if (s_interrupt_handler[interrupt_number]->type() == HandlerType::UnhandledInterruptHandler) {
  366. dbg() << "Trying to unregister unused handler (?)";
  367. return;
  368. }
  369. if (s_interrupt_handler[interrupt_number]->is_shared_handler() && !s_interrupt_handler[interrupt_number]->is_sharing_with_others()) {
  370. ASSERT(s_interrupt_handler[interrupt_number]->type() == HandlerType::SharedIRQHandler);
  371. static_cast<SharedIRQHandler*>(s_interrupt_handler[interrupt_number])->unregister_handler(handler);
  372. if (!static_cast<SharedIRQHandler*>(s_interrupt_handler[interrupt_number])->sharing_devices_count()) {
  373. revert_to_unused_handler(interrupt_number);
  374. }
  375. return;
  376. }
  377. if (!s_interrupt_handler[interrupt_number]->is_shared_handler()) {
  378. ASSERT(s_interrupt_handler[interrupt_number]->type() == HandlerType::IRQHandler);
  379. revert_to_unused_handler(interrupt_number);
  380. return;
  381. }
  382. ASSERT_NOT_REACHED();
  383. }
  384. void register_interrupt_handler(u8 index, void (*f)())
  385. {
  386. s_idt[index].low = 0x00080000 | LSW((f));
  387. s_idt[index].high = ((u32)(f)&0xffff0000) | 0x8e00;
  388. }
  389. void register_user_callable_interrupt_handler(u8 index, void (*f)())
  390. {
  391. s_idt[index].low = 0x00080000 | LSW((f));
  392. s_idt[index].high = ((u32)(f)&0xffff0000) | 0xef00;
  393. }
  394. void flush_idt()
  395. {
  396. asm("lidt %0" ::"m"(s_idtr));
  397. }
  398. static void idt_init()
  399. {
  400. s_idtr.address = s_idt;
  401. s_idtr.limit = 0x100 * 8 - 1;
  402. for (u8 i = 0xff; i > 0x10; --i)
  403. register_interrupt_handler(i, unimp_trap);
  404. register_interrupt_handler(0x00, divide_error_asm_entry);
  405. register_user_callable_interrupt_handler(0x01, debug_asm_entry);
  406. register_interrupt_handler(0x02, _exception2);
  407. register_user_callable_interrupt_handler(0x03, breakpoint_asm_entry);
  408. register_interrupt_handler(0x04, _exception4);
  409. register_interrupt_handler(0x05, _exception5);
  410. register_interrupt_handler(0x06, illegal_instruction_asm_entry);
  411. register_interrupt_handler(0x07, fpu_exception_asm_entry);
  412. register_interrupt_handler(0x08, _exception8);
  413. register_interrupt_handler(0x09, _exception9);
  414. register_interrupt_handler(0x0a, _exception10);
  415. register_interrupt_handler(0x0b, _exception11);
  416. register_interrupt_handler(0x0c, _exception12);
  417. register_interrupt_handler(0x0d, general_protection_fault_asm_entry);
  418. register_interrupt_handler(0x0e, page_fault_asm_entry);
  419. register_interrupt_handler(0x0f, _exception15);
  420. register_interrupt_handler(0x10, _exception16);
  421. register_interrupt_handler(0x50, interrupt_0_asm_entry);
  422. register_interrupt_handler(0x51, interrupt_1_asm_entry);
  423. register_interrupt_handler(0x52, interrupt_2_asm_entry);
  424. register_interrupt_handler(0x53, interrupt_3_asm_entry);
  425. register_interrupt_handler(0x54, interrupt_4_asm_entry);
  426. register_interrupt_handler(0x55, interrupt_5_asm_entry);
  427. register_interrupt_handler(0x56, interrupt_6_asm_entry);
  428. register_interrupt_handler(0x57, interrupt_7_asm_entry);
  429. register_interrupt_handler(0x58, interrupt_8_asm_entry);
  430. register_interrupt_handler(0x59, interrupt_9_asm_entry);
  431. register_interrupt_handler(0x5a, interrupt_10_asm_entry);
  432. register_interrupt_handler(0x5b, interrupt_11_asm_entry);
  433. register_interrupt_handler(0x5c, interrupt_12_asm_entry);
  434. register_interrupt_handler(0x5d, interrupt_13_asm_entry);
  435. register_interrupt_handler(0x5e, interrupt_14_asm_entry);
  436. register_interrupt_handler(0x5f, interrupt_15_asm_entry);
  437. register_interrupt_handler(0x60, interrupt_16_asm_entry);
  438. register_interrupt_handler(0x61, interrupt_17_asm_entry);
  439. register_interrupt_handler(0x62, interrupt_18_asm_entry);
  440. register_interrupt_handler(0x63, interrupt_19_asm_entry);
  441. register_interrupt_handler(0x64, interrupt_20_asm_entry);
  442. register_interrupt_handler(0x65, interrupt_21_asm_entry);
  443. register_interrupt_handler(0x66, interrupt_22_asm_entry);
  444. register_interrupt_handler(0x67, interrupt_23_asm_entry);
  445. register_interrupt_handler(0x68, interrupt_24_asm_entry);
  446. register_interrupt_handler(0x69, interrupt_25_asm_entry);
  447. register_interrupt_handler(0x6a, interrupt_26_asm_entry);
  448. register_interrupt_handler(0x6b, interrupt_27_asm_entry);
  449. register_interrupt_handler(0x6c, interrupt_28_asm_entry);
  450. register_interrupt_handler(0x6d, interrupt_29_asm_entry);
  451. register_interrupt_handler(0x6e, interrupt_30_asm_entry);
  452. register_interrupt_handler(0x6f, interrupt_31_asm_entry);
  453. register_interrupt_handler(0x70, interrupt_32_asm_entry);
  454. register_interrupt_handler(0x71, interrupt_33_asm_entry);
  455. register_interrupt_handler(0x72, interrupt_34_asm_entry);
  456. register_interrupt_handler(0x73, interrupt_35_asm_entry);
  457. register_interrupt_handler(0x74, interrupt_36_asm_entry);
  458. register_interrupt_handler(0x75, interrupt_37_asm_entry);
  459. register_interrupt_handler(0x76, interrupt_38_asm_entry);
  460. register_interrupt_handler(0x77, interrupt_39_asm_entry);
  461. register_interrupt_handler(0x78, interrupt_40_asm_entry);
  462. register_interrupt_handler(0x79, interrupt_41_asm_entry);
  463. register_interrupt_handler(0x7a, interrupt_42_asm_entry);
  464. register_interrupt_handler(0x7b, interrupt_43_asm_entry);
  465. register_interrupt_handler(0x7c, interrupt_44_asm_entry);
  466. register_interrupt_handler(0x7d, interrupt_45_asm_entry);
  467. register_interrupt_handler(0x7e, interrupt_46_asm_entry);
  468. register_interrupt_handler(0x7f, interrupt_47_asm_entry);
  469. register_interrupt_handler(0x80, interrupt_48_asm_entry);
  470. register_interrupt_handler(0x81, interrupt_49_asm_entry);
  471. register_interrupt_handler(0x82, interrupt_50_asm_entry);
  472. register_interrupt_handler(0x83, interrupt_51_asm_entry);
  473. register_interrupt_handler(0x84, interrupt_52_asm_entry);
  474. register_interrupt_handler(0x85, interrupt_53_asm_entry);
  475. register_interrupt_handler(0x86, interrupt_54_asm_entry);
  476. register_interrupt_handler(0x87, interrupt_55_asm_entry);
  477. register_interrupt_handler(0x88, interrupt_56_asm_entry);
  478. register_interrupt_handler(0x89, interrupt_57_asm_entry);
  479. register_interrupt_handler(0x8a, interrupt_58_asm_entry);
  480. register_interrupt_handler(0x8b, interrupt_59_asm_entry);
  481. register_interrupt_handler(0x8c, interrupt_60_asm_entry);
  482. register_interrupt_handler(0x8d, interrupt_61_asm_entry);
  483. register_interrupt_handler(0x8e, interrupt_62_asm_entry);
  484. register_interrupt_handler(0x8f, interrupt_63_asm_entry);
  485. register_interrupt_handler(0x90, interrupt_64_asm_entry);
  486. register_interrupt_handler(0x91, interrupt_65_asm_entry);
  487. register_interrupt_handler(0x92, interrupt_66_asm_entry);
  488. register_interrupt_handler(0x93, interrupt_67_asm_entry);
  489. register_interrupt_handler(0x94, interrupt_68_asm_entry);
  490. register_interrupt_handler(0x95, interrupt_69_asm_entry);
  491. register_interrupt_handler(0x96, interrupt_70_asm_entry);
  492. register_interrupt_handler(0x97, interrupt_71_asm_entry);
  493. register_interrupt_handler(0x98, interrupt_72_asm_entry);
  494. register_interrupt_handler(0x99, interrupt_73_asm_entry);
  495. register_interrupt_handler(0x9a, interrupt_74_asm_entry);
  496. register_interrupt_handler(0x9b, interrupt_75_asm_entry);
  497. register_interrupt_handler(0x9c, interrupt_76_asm_entry);
  498. register_interrupt_handler(0x9d, interrupt_77_asm_entry);
  499. register_interrupt_handler(0x9e, interrupt_78_asm_entry);
  500. register_interrupt_handler(0x9f, interrupt_79_asm_entry);
  501. register_interrupt_handler(0xa0, interrupt_80_asm_entry);
  502. register_interrupt_handler(0xa1, interrupt_81_asm_entry);
  503. register_interrupt_handler(0xa2, interrupt_82_asm_entry);
  504. register_interrupt_handler(0xa3, interrupt_83_asm_entry);
  505. register_interrupt_handler(0xa4, interrupt_84_asm_entry);
  506. register_interrupt_handler(0xa5, interrupt_85_asm_entry);
  507. register_interrupt_handler(0xa6, interrupt_86_asm_entry);
  508. register_interrupt_handler(0xa7, interrupt_87_asm_entry);
  509. register_interrupt_handler(0xa8, interrupt_88_asm_entry);
  510. register_interrupt_handler(0xa9, interrupt_89_asm_entry);
  511. register_interrupt_handler(0xaa, interrupt_90_asm_entry);
  512. register_interrupt_handler(0xab, interrupt_91_asm_entry);
  513. register_interrupt_handler(0xac, interrupt_92_asm_entry);
  514. register_interrupt_handler(0xad, interrupt_93_asm_entry);
  515. register_interrupt_handler(0xae, interrupt_94_asm_entry);
  516. register_interrupt_handler(0xaf, interrupt_95_asm_entry);
  517. register_interrupt_handler(0xb0, interrupt_96_asm_entry);
  518. register_interrupt_handler(0xb1, interrupt_97_asm_entry);
  519. register_interrupt_handler(0xb2, interrupt_98_asm_entry);
  520. register_interrupt_handler(0xb3, interrupt_99_asm_entry);
  521. register_interrupt_handler(0xb4, interrupt_100_asm_entry);
  522. register_interrupt_handler(0xb5, interrupt_101_asm_entry);
  523. register_interrupt_handler(0xb6, interrupt_102_asm_entry);
  524. register_interrupt_handler(0xb7, interrupt_103_asm_entry);
  525. register_interrupt_handler(0xb8, interrupt_104_asm_entry);
  526. register_interrupt_handler(0xb9, interrupt_105_asm_entry);
  527. register_interrupt_handler(0xba, interrupt_106_asm_entry);
  528. register_interrupt_handler(0xbb, interrupt_107_asm_entry);
  529. register_interrupt_handler(0xbc, interrupt_108_asm_entry);
  530. register_interrupt_handler(0xbd, interrupt_109_asm_entry);
  531. register_interrupt_handler(0xbe, interrupt_110_asm_entry);
  532. register_interrupt_handler(0xbf, interrupt_111_asm_entry);
  533. register_interrupt_handler(0xc0, interrupt_112_asm_entry);
  534. register_interrupt_handler(0xc1, interrupt_113_asm_entry);
  535. register_interrupt_handler(0xc2, interrupt_114_asm_entry);
  536. register_interrupt_handler(0xc3, interrupt_115_asm_entry);
  537. register_interrupt_handler(0xc4, interrupt_116_asm_entry);
  538. register_interrupt_handler(0xc5, interrupt_117_asm_entry);
  539. register_interrupt_handler(0xc6, interrupt_118_asm_entry);
  540. register_interrupt_handler(0xc7, interrupt_119_asm_entry);
  541. register_interrupt_handler(0xc8, interrupt_120_asm_entry);
  542. register_interrupt_handler(0xc9, interrupt_121_asm_entry);
  543. register_interrupt_handler(0xca, interrupt_122_asm_entry);
  544. register_interrupt_handler(0xcb, interrupt_123_asm_entry);
  545. register_interrupt_handler(0xcc, interrupt_124_asm_entry);
  546. register_interrupt_handler(0xcd, interrupt_125_asm_entry);
  547. register_interrupt_handler(0xce, interrupt_126_asm_entry);
  548. register_interrupt_handler(0xcf, interrupt_127_asm_entry);
  549. dbg() << "Installing Unhandled Handlers";
  550. for (u8 i = 0; i < GENERIC_INTERRUPT_HANDLERS_COUNT; ++i) {
  551. new UnhandledInterruptHandler(i);
  552. }
  553. flush_idt();
  554. }
  555. void load_task_register(u16 selector)
  556. {
  557. asm("ltr %0" ::"r"(selector));
  558. }
  559. void handle_interrupt(TrapFrame* trap)
  560. {
  561. clac();
  562. auto& regs = *trap->regs;
  563. ASSERT(regs.isr_number >= IRQ_VECTOR_BASE && regs.isr_number <= (IRQ_VECTOR_BASE + GENERIC_INTERRUPT_HANDLERS_COUNT));
  564. u8 irq = (u8)(regs.isr_number - 0x50);
  565. ASSERT(s_interrupt_handler[irq]);
  566. s_interrupt_handler[irq]->handle_interrupt(regs);
  567. s_interrupt_handler[irq]->eoi();
  568. }
  569. void enter_trap_no_irq(TrapFrame* trap)
  570. {
  571. Processor::current().enter_trap(*trap, false);
  572. }
  573. void enter_trap(TrapFrame* trap)
  574. {
  575. Processor::current().enter_trap(*trap, true);
  576. }
  577. void exit_trap(TrapFrame* trap)
  578. {
  579. return Processor::current().exit_trap(*trap);
  580. }
  581. static void sse_init()
  582. {
  583. asm volatile(
  584. "mov %cr0, %eax\n"
  585. "andl $0xfffffffb, %eax\n"
  586. "orl $0x2, %eax\n"
  587. "mov %eax, %cr0\n"
  588. "mov %cr4, %eax\n"
  589. "orl $0x600, %eax\n"
  590. "mov %eax, %cr4\n");
  591. }
  592. u32 read_cr0()
  593. {
  594. u32 cr0;
  595. asm("movl %%cr0, %%eax"
  596. : "=a"(cr0));
  597. return cr0;
  598. }
  599. u32 read_cr3()
  600. {
  601. u32 cr3;
  602. asm("movl %%cr3, %%eax"
  603. : "=a"(cr3));
  604. return cr3;
  605. }
  606. void write_cr3(u32 cr3)
  607. {
  608. asm volatile("movl %%eax, %%cr3" ::"a"(cr3)
  609. : "memory");
  610. }
  611. u32 read_cr4()
  612. {
  613. u32 cr4;
  614. asm("movl %%cr4, %%eax"
  615. : "=a"(cr4));
  616. return cr4;
  617. }
  618. u32 read_dr6()
  619. {
  620. u32 dr6;
  621. asm("movl %%dr6, %%eax"
  622. : "=a"(dr6));
  623. return dr6;
  624. }
  625. FPUState Processor::s_clean_fpu_state;
  626. static Vector<Processor*>* s_processors;
  627. static SpinLock s_processor_lock;
  628. Vector<Processor*>& Processor::processors()
  629. {
  630. ASSERT(s_processors);
  631. return *s_processors;
  632. }
  633. Processor& Processor::by_id(u32 cpu)
  634. {
  635. // s_processors does not need to be protected by a lock of any kind.
  636. // It is populated early in the boot process, and the BSP is waiting
  637. // for all APs to finish, after which this array never gets modified
  638. // again, so it's safe to not protect access to it here
  639. auto& procs = processors();
  640. ASSERT(procs[cpu] != nullptr);
  641. ASSERT(procs.size() > cpu);
  642. return *procs[cpu];
  643. }
  644. void Processor::cpu_detect()
  645. {
  646. // NOTE: This is called during Processor::early_initialize, we cannot
  647. // safely log at this point because we don't have kmalloc
  648. // initialized yet!
  649. auto set_feature =
  650. [&](CPUFeature f) {
  651. m_features = static_cast<CPUFeature>(static_cast<u32>(m_features) | static_cast<u32>(f));
  652. };
  653. m_features = static_cast<CPUFeature>(0);
  654. CPUID processor_info(0x1);
  655. if (processor_info.edx() & (1 << 6))
  656. set_feature(CPUFeature::PAE);
  657. if (processor_info.edx() & (1 << 13))
  658. set_feature(CPUFeature::PGE);
  659. if (processor_info.edx() & (1 << 25))
  660. set_feature(CPUFeature::SSE);
  661. if (processor_info.edx() & (1 << 4))
  662. set_feature(CPUFeature::TSC);
  663. if (processor_info.ecx() & (1 << 30))
  664. set_feature(CPUFeature::RDRAND);
  665. CPUID extended_processor_info(0x80000001);
  666. if (extended_processor_info.edx() & (1 << 20))
  667. set_feature(CPUFeature::NX);
  668. CPUID extended_features(0x7);
  669. if (extended_features.ebx() & (1 << 20))
  670. set_feature(CPUFeature::SMAP);
  671. if (extended_features.ebx() & (1 << 7))
  672. set_feature(CPUFeature::SMEP);
  673. if (extended_features.ecx() & (1 << 2))
  674. set_feature(CPUFeature::UMIP);
  675. if (extended_features.ebx() & (1 << 18))
  676. set_feature(CPUFeature::RDSEED);
  677. }
  678. void Processor::cpu_setup()
  679. {
  680. // NOTE: This is called during Processor::early_initialize, we cannot
  681. // safely log at this point because we don't have kmalloc
  682. // initialized yet!
  683. cpu_detect();
  684. if (has_feature(CPUFeature::SSE))
  685. sse_init();
  686. asm volatile(
  687. "movl %%cr0, %%eax\n"
  688. "orl $0x00010000, %%eax\n"
  689. "movl %%eax, %%cr0\n" ::
  690. : "%eax", "memory");
  691. if (has_feature(CPUFeature::PGE)) {
  692. // Turn on CR4.PGE so the CPU will respect the G bit in page tables.
  693. asm volatile(
  694. "mov %cr4, %eax\n"
  695. "orl $0x80, %eax\n"
  696. "mov %eax, %cr4\n");
  697. }
  698. if (has_feature(CPUFeature::NX)) {
  699. // Turn on IA32_EFER.NXE
  700. asm volatile(
  701. "movl $0xc0000080, %ecx\n"
  702. "rdmsr\n"
  703. "orl $0x800, %eax\n"
  704. "wrmsr\n");
  705. }
  706. if (has_feature(CPUFeature::SMEP)) {
  707. // Turn on CR4.SMEP
  708. asm volatile(
  709. "mov %cr4, %eax\n"
  710. "orl $0x100000, %eax\n"
  711. "mov %eax, %cr4\n");
  712. }
  713. if (has_feature(CPUFeature::SMAP)) {
  714. // Turn on CR4.SMAP
  715. asm volatile(
  716. "mov %cr4, %eax\n"
  717. "orl $0x200000, %eax\n"
  718. "mov %eax, %cr4\n");
  719. }
  720. if (has_feature(CPUFeature::UMIP)) {
  721. asm volatile(
  722. "mov %cr4, %eax\n"
  723. "orl $0x800, %eax\n"
  724. "mov %eax, %cr4\n");
  725. }
  726. if (has_feature(CPUFeature::TSC)) {
  727. asm volatile(
  728. "mov %cr4, %eax\n"
  729. "orl $0x4, %eax\n"
  730. "mov %eax, %cr4\n");
  731. }
  732. }
  733. String Processor::features_string() const
  734. {
  735. StringBuilder builder;
  736. auto feature_to_str =
  737. [](CPUFeature f) -> const char*
  738. {
  739. switch (f) {
  740. case CPUFeature::NX:
  741. return "nx";
  742. case CPUFeature::PAE:
  743. return "pae";
  744. case CPUFeature::PGE:
  745. return "pge";
  746. case CPUFeature::RDRAND:
  747. return "rdrand";
  748. case CPUFeature::RDSEED:
  749. return "rdseed";
  750. case CPUFeature::SMAP:
  751. return "smap";
  752. case CPUFeature::SMEP:
  753. return "smep";
  754. case CPUFeature::SSE:
  755. return "sse";
  756. case CPUFeature::TSC:
  757. return "tsc";
  758. case CPUFeature::UMIP:
  759. return "umip";
  760. // no default statement here intentionally so that we get
  761. // a warning if a new feature is forgotten to be added here
  762. }
  763. // Shouldn't ever happen
  764. return "???";
  765. };
  766. bool first = true;
  767. for (u32 flag = 1; flag < sizeof(m_features) * 8; flag <<= 1) {
  768. if ((static_cast<u32>(m_features) & flag) != 0) {
  769. if (first)
  770. first = false;
  771. else
  772. builder.append(' ');
  773. auto str = feature_to_str(static_cast<CPUFeature>(flag));
  774. builder.append(str, strlen(str));
  775. }
  776. }
  777. return builder.build();
  778. }
  779. void Processor::early_initialize(u32 cpu)
  780. {
  781. m_self = this;
  782. m_cpu = cpu;
  783. m_in_irq = 0;
  784. m_in_critical = 0;
  785. m_invoke_scheduler_async = false;
  786. m_scheduler_initialized = false;
  787. m_idle_thread = nullptr;
  788. m_current_thread = nullptr;
  789. m_mm_data = nullptr;
  790. m_info = nullptr;
  791. cpu_setup();
  792. gdt_init();
  793. ASSERT(&current() == this); // sanity check
  794. }
  795. void Processor::initialize(u32 cpu)
  796. {
  797. ASSERT(m_self == this);
  798. ASSERT(&current() == this); // sanity check
  799. klog() << "CPU[" << id() << "]: Supported features: " << features_string();
  800. if (!has_feature(CPUFeature::RDRAND))
  801. klog() << "CPU[" << id() << "]: No RDRAND support detected, randomness will be poor";
  802. if (cpu == 0)
  803. idt_init();
  804. else
  805. flush_idt();
  806. if (cpu == 0) {
  807. ASSERT((FlatPtr(&s_clean_fpu_state) & 0xF) == 0);
  808. asm volatile("fninit");
  809. asm volatile("fxsave %0"
  810. : "=m"(s_clean_fpu_state));
  811. }
  812. m_info = new ProcessorInfo(*this);
  813. {
  814. ScopedSpinLock lock(s_processor_lock);
  815. // We need to prevent races between APs starting up at the same time
  816. if (!s_processors)
  817. s_processors = new Vector<Processor*>();
  818. if (cpu >= s_processors->size())
  819. s_processors->resize(cpu + 1);
  820. (*s_processors)[cpu] = this;
  821. }
  822. klog() << "CPU[" << cpu << "]: initialized Processor at " << VirtualAddress(FlatPtr(this));
  823. }
  824. void Processor::write_raw_gdt_entry(u16 selector, u32 low, u32 high)
  825. {
  826. u16 i = (selector & 0xfffc) >> 3;
  827. u32 prev_gdt_length = m_gdt_length;
  828. if (i > m_gdt_length) {
  829. m_gdt_length = i + 1;
  830. ASSERT(m_gdt_length <= sizeof(m_gdt) / sizeof(m_gdt[0]));
  831. m_gdtr.limit = (m_gdt_length + 1) * 8 - 1;
  832. }
  833. m_gdt[i].low = low;
  834. m_gdt[i].high = high;
  835. // clear selectors we may have skipped
  836. while (i < prev_gdt_length) {
  837. m_gdt[i].low = 0;
  838. m_gdt[i].high = 0;
  839. i++;
  840. }
  841. }
  842. void Processor::write_gdt_entry(u16 selector, Descriptor& descriptor)
  843. {
  844. write_raw_gdt_entry(selector, descriptor.low, descriptor.high);
  845. }
  846. Descriptor& Processor::get_gdt_entry(u16 selector)
  847. {
  848. u16 i = (selector & 0xfffc) >> 3;
  849. return *(Descriptor*)(&m_gdt[i]);
  850. }
  851. void Processor::flush_gdt()
  852. {
  853. m_gdtr.address = m_gdt;
  854. m_gdtr.limit = (m_gdt_length * 8) - 1;
  855. asm volatile("lgdt %0" ::"m"(m_gdtr)
  856. : "memory");
  857. }
  858. const DescriptorTablePointer& Processor::get_gdtr()
  859. {
  860. return m_gdtr;
  861. }
  862. bool Processor::get_context_frame_ptr(Thread& thread, u32& frame_ptr, u32& eip)
  863. {
  864. ScopedCritical critical;
  865. auto& proc = Processor::current();
  866. if (&thread == proc.current_thread()) {
  867. ASSERT(thread.state() == Thread::Running);
  868. asm volatile("movl %%ebp, %%eax"
  869. : "=g"(frame_ptr));
  870. } else {
  871. // Since the thread may be running on another processor, there
  872. // is a chance a context switch may happen while we're trying
  873. // to get it. It also won't be entirely accurate and merely
  874. // reflect the status at the last context switch.
  875. ScopedSpinLock lock(g_scheduler_lock);
  876. if (thread.state() == Thread::Running) {
  877. ASSERT(thread.cpu() != proc.id());
  878. // TODO: If this is the case, the thread is currently running
  879. // on another processor. We can't trust the kernel stack as
  880. // it may be changing at any time. We need to probably send
  881. // an ICI to that processor, have it walk the stack and wait
  882. // until it returns the data back to us
  883. dbg() << "CPU[" << proc.id() << "] getting stack for "
  884. << thread << " on other CPU# " << thread.cpu() << " not yet implemented!";
  885. frame_ptr = eip = 0; // TODO
  886. return false;
  887. } else {
  888. // We need to retrieve ebp from what was last pushed to the kernel
  889. // stack. Before switching out of that thread, it switch_context
  890. // pushed the callee-saved registers, and the last of them happens
  891. // to be ebp.
  892. auto& tss = thread.tss();
  893. u32* stack_top = reinterpret_cast<u32*>(tss.esp);
  894. frame_ptr = stack_top[0];
  895. eip = tss.eip;
  896. }
  897. }
  898. return true;
  899. }
  900. extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread)
  901. {
  902. ASSERT(from_thread == to_thread || from_thread->state() != Thread::Running);
  903. ASSERT(to_thread->state() == Thread::Running);
  904. auto& processor = Processor::current();
  905. processor.set_current_thread(*to_thread);
  906. auto& from_tss = from_thread->tss();
  907. auto& to_tss = to_thread->tss();
  908. asm volatile("fxsave %0"
  909. : "=m"(from_thread->fpu_state()));
  910. from_tss.fs = get_fs();
  911. from_tss.gs = get_gs();
  912. set_fs(to_tss.fs);
  913. set_gs(to_tss.gs);
  914. auto& tls_descriptor = processor.get_gdt_entry(GDT_SELECTOR_TLS);
  915. tls_descriptor.set_base(to_thread->thread_specific_data().as_ptr());
  916. tls_descriptor.set_limit(to_thread->thread_specific_region_size());
  917. if (from_tss.cr3 != to_tss.cr3)
  918. write_cr3(to_tss.cr3);
  919. to_thread->set_cpu(processor.id());
  920. asm volatile("fxrstor %0"
  921. ::"m"(to_thread->fpu_state()));
  922. // TODO: debug registers
  923. // TODO: ioperm?
  924. }
  925. #define ENTER_THREAD_CONTEXT_ARGS_SIZE (2 * 4) // to_thread, from_thread
  926. void Processor::switch_context(Thread*& from_thread, Thread*& to_thread)
  927. {
  928. ASSERT(!in_irq());
  929. ASSERT(m_in_critical == 1);
  930. ASSERT(is_kernel_mode());
  931. #ifdef CONTEXT_SWITCH_DEBUG
  932. dbg() << "switch_context --> switching out of: " << VirtualAddress(from_thread) << " " << *from_thread;
  933. #endif
  934. // Switch to new thread context, passing from_thread and to_thread
  935. // through to the new context using registers edx and eax
  936. asm volatile(
  937. // NOTE: changing how much we push to the stack affects
  938. // SWITCH_CONTEXT_TO_STACK_SIZE and thread_context_first_enter()!
  939. "pushfl \n"
  940. "pushl %%ebx \n"
  941. "pushl %%esi \n"
  942. "pushl %%edi \n"
  943. "pushl %%ebp \n"
  944. "movl %%esp, %[from_esp] \n"
  945. "movl $1f, %[from_eip] \n"
  946. "movl %[to_esp0], %%ebx \n"
  947. "movl %%ebx, %[tss_esp0] \n"
  948. "movl %[to_esp], %%esp \n"
  949. "pushl %[to_thread] \n"
  950. "pushl %[from_thread] \n"
  951. "pushl %[to_eip] \n"
  952. "cld \n"
  953. "jmp enter_thread_context \n"
  954. "1: \n"
  955. "popl %%edx \n"
  956. "popl %%eax \n"
  957. "popl %%ebp \n"
  958. "popl %%edi \n"
  959. "popl %%esi \n"
  960. "popl %%ebx \n"
  961. "popfl \n"
  962. : [from_esp] "=m" (from_thread->tss().esp),
  963. [from_eip] "=m" (from_thread->tss().eip),
  964. [tss_esp0] "=m" (m_tss.esp0),
  965. "=d" (from_thread), // needed so that from_thread retains the correct value
  966. "=a" (to_thread) // needed so that to_thread retains the correct value
  967. : [to_esp] "g" (to_thread->tss().esp),
  968. [to_esp0] "g" (to_thread->tss().esp0),
  969. [to_eip] "c" (to_thread->tss().eip),
  970. [from_thread] "d" (from_thread),
  971. [to_thread] "a" (to_thread)
  972. );
  973. #ifdef CONTEXT_SWITCH_DEBUG
  974. dbg() << "switch_context <-- from " << VirtualAddress(from_thread) << " " << *from_thread << " to " << VirtualAddress(to_thread) << " " << *to_thread;
  975. #endif
  976. }
  977. extern "C" void context_first_init(Thread* from_thread, Thread* to_thread, TrapFrame* trap)
  978. {
  979. ASSERT(!are_interrupts_enabled());
  980. ASSERT(is_kernel_mode());
  981. (void)from_thread;
  982. (void)to_thread;
  983. (void)trap;
  984. #ifdef CONTEXT_SWITCH_DEBUG
  985. dbg() << "switch_context <-- from " << VirtualAddress(from_thread) << " " << *from_thread << " to " << VirtualAddress(to_thread) << " " << *to_thread << " (context_first_init)";
  986. #endif
  987. ASSERT(to_thread == Thread::current());
  988. Scheduler::enter_current(*from_thread);
  989. if (to_thread->process().wait_for_tracer_at_next_execve()) {
  990. to_thread->send_urgent_signal_to_self(SIGSTOP);
  991. }
  992. // Since we got here and don't have Scheduler::context_switch in the
  993. // call stack (because this is the first time we switched into this
  994. // context), we need to unlock the scheduler lock manually. We're
  995. // using the flags initially set up by init_context
  996. g_scheduler_lock.unlock(trap->regs->eflags);
  997. }
  998. extern "C" void thread_context_first_enter(void);
  999. asm(
  1000. // enter_thread_context returns to here first time a thread is executing
  1001. ".globl thread_context_first_enter \n"
  1002. "thread_context_first_enter: \n"
  1003. // switch_context will have pushed from_thread and to_thread to our new
  1004. // stack prior to thread_context_first_enter() being called, and the
  1005. // pointer to TrapFrame was the top of the stack before that
  1006. " movl 8(%esp), %ebx \n" // save pointer to TrapFrame
  1007. " cld \n"
  1008. " call context_first_init \n"
  1009. " addl $" __STRINGIFY(ENTER_THREAD_CONTEXT_ARGS_SIZE) ", %esp \n"
  1010. " movl %ebx, 0(%esp) \n" // push pointer to TrapFrame
  1011. " jmp common_trap_exit \n"
  1012. );
  1013. u32 Processor::init_context(Thread& thread, bool leave_crit)
  1014. {
  1015. ASSERT(is_kernel_mode());
  1016. ASSERT(g_scheduler_lock.is_locked());
  1017. if (leave_crit) {
  1018. // Leave the critical section we set up in in Process::exec,
  1019. // but because we still have the scheduler lock we should end up with 1
  1020. m_in_critical--; // leave it without triggering anything or restoring flags
  1021. ASSERT(in_critical() == 1);
  1022. }
  1023. const u32 kernel_stack_top = thread.kernel_stack_top();
  1024. u32 stack_top = kernel_stack_top;
  1025. // TODO: handle NT?
  1026. ASSERT((cpu_flags() & 0x24000) == 0); // Assume !(NT | VM)
  1027. auto& tss = thread.tss();
  1028. bool return_to_user = (tss.cs & 3) != 0;
  1029. // make room for an interrupt frame
  1030. if (!return_to_user) {
  1031. // userspace_esp and userspace_ss are not popped off by iret
  1032. // unless we're switching back to user mode
  1033. stack_top -= sizeof(RegisterState) - 2 * sizeof(u32);
  1034. } else {
  1035. stack_top -= sizeof(RegisterState);
  1036. }
  1037. // we want to end up 16-byte aligned, %esp + 4 should be aligned
  1038. stack_top -= sizeof(u32);
  1039. *reinterpret_cast<u32*>(kernel_stack_top - 4) = 0;
  1040. // set up the stack so that after returning from thread_context_first_enter()
  1041. // we will end up either in kernel mode or user mode, depending on how the thread is set up
  1042. // However, the first step is to always start in kernel mode with thread_context_first_enter
  1043. RegisterState& iretframe = *reinterpret_cast<RegisterState*>(stack_top);
  1044. iretframe.ss = tss.ss;
  1045. iretframe.gs = tss.gs;
  1046. iretframe.fs = tss.fs;
  1047. iretframe.es = tss.es;
  1048. iretframe.ds = tss.ds;
  1049. iretframe.edi = tss.edi;
  1050. iretframe.esi = tss.esi;
  1051. iretframe.ebp = tss.ebp;
  1052. iretframe.esp = 0;
  1053. iretframe.ebx = tss.ebx;
  1054. iretframe.edx = tss.edx;
  1055. iretframe.ecx = tss.ecx;
  1056. iretframe.eax = tss.eax;
  1057. iretframe.eflags = tss.eflags;
  1058. iretframe.eip = tss.eip;
  1059. iretframe.cs = tss.cs;
  1060. if (return_to_user) {
  1061. iretframe.userspace_esp = tss.esp;
  1062. iretframe.userspace_ss = tss.ss;
  1063. }
  1064. // make space for a trap frame
  1065. stack_top -= sizeof(TrapFrame);
  1066. TrapFrame& trap = *reinterpret_cast<TrapFrame*>(stack_top);
  1067. trap.regs = &iretframe;
  1068. trap.prev_irq_level = 0;
  1069. stack_top -= sizeof(u32); // pointer to TrapFrame
  1070. *reinterpret_cast<u32*>(stack_top) = stack_top + 4;
  1071. #ifdef CONTEXT_SWITCH_DEBUG
  1072. if (return_to_user)
  1073. dbg() << "init_context " << thread << " (" << VirtualAddress(&thread) << ") set up to execute at eip: " << String::format("%02x:%08x", iretframe.cs, (u32)tss.eip) << " esp: " << VirtualAddress(tss.esp) << " stack top: " << VirtualAddress(stack_top) << " user esp: " << String::format("%02x:%08x", iretframe.userspace_ss, (u32)iretframe.userspace_esp);
  1074. else
  1075. dbg() << "init_context " << thread << " (" << VirtualAddress(&thread) << ") set up to execute at eip: " << String::format("%02x:%08x", iretframe.cs, (u32)tss.eip) << " esp: " << VirtualAddress(tss.esp) << " stack top: " << VirtualAddress(stack_top);
  1076. #endif
  1077. // make switch_context() always first return to thread_context_first_enter()
  1078. // in kernel mode, so set up these values so that we end up popping iretframe
  1079. // off the stack right after the context switch completed, at which point
  1080. // control is transferred to what iretframe is pointing to.
  1081. tss.eip = FlatPtr(&thread_context_first_enter);
  1082. tss.esp0 = kernel_stack_top;
  1083. tss.esp = stack_top;
  1084. tss.cs = GDT_SELECTOR_CODE0;
  1085. tss.ds = GDT_SELECTOR_DATA0;
  1086. tss.es = GDT_SELECTOR_DATA0;
  1087. tss.gs = GDT_SELECTOR_DATA0;
  1088. tss.ss = GDT_SELECTOR_DATA0;
  1089. tss.fs = GDT_SELECTOR_PROC;
  1090. return stack_top;
  1091. }
  1092. extern "C" u32 do_init_context(Thread* thread, u32 flags)
  1093. {
  1094. ASSERT_INTERRUPTS_DISABLED();
  1095. thread->tss().eflags = flags;
  1096. return Processor::current().init_context(*thread, true);
  1097. }
  1098. extern "C" void do_assume_context(Thread* thread, u32 flags);
  1099. asm(
  1100. ".global do_assume_context \n"
  1101. "do_assume_context: \n"
  1102. " movl 4(%esp), %ebx \n"
  1103. " movl 8(%esp), %esi \n"
  1104. // We're going to call Processor::init_context, so just make sure
  1105. // we have enough stack space so we don't stomp over it
  1106. " subl $(" __STRINGIFY(4 + REGISTER_STATE_SIZE + TRAP_FRAME_SIZE + 4) "), %esp \n"
  1107. " pushl %esi \n"
  1108. " pushl %ebx \n"
  1109. " cld \n"
  1110. " call do_init_context \n"
  1111. " addl $8, %esp \n"
  1112. " movl %eax, %esp \n" // move stack pointer to what Processor::init_context set up for us
  1113. " pushl %ebx \n" // push to_thread
  1114. " pushl %ebx \n" // push from_thread
  1115. " pushl $thread_context_first_enter \n" // should be same as tss.eip
  1116. " jmp enter_thread_context \n"
  1117. );
  1118. void Processor::assume_context(Thread& thread, u32 flags)
  1119. {
  1120. #ifdef CONTEXT_SWITCH_DEBUG
  1121. dbg() << "Assume context for thread " << VirtualAddress(&thread) << " " << thread;
  1122. #endif
  1123. ASSERT_INTERRUPTS_DISABLED();
  1124. // in_critical() should be 2 here. The critical section in Process::exec
  1125. // and then the scheduler lock
  1126. ASSERT(Processor::current().in_critical() == 2);
  1127. do_assume_context(&thread, flags);
  1128. ASSERT_NOT_REACHED();
  1129. }
  1130. void Processor::initialize_context_switching(Thread& initial_thread)
  1131. {
  1132. ASSERT(initial_thread.process().is_ring0());
  1133. auto& tss = initial_thread.tss();
  1134. m_tss = tss;
  1135. m_tss.esp0 = tss.esp0;
  1136. m_tss.ss0 = GDT_SELECTOR_DATA0;
  1137. // user mode needs to be able to switch to kernel mode:
  1138. m_tss.cs = m_tss.ds = m_tss.es = m_tss.gs = m_tss.ss = GDT_SELECTOR_CODE0 | 3;
  1139. m_tss.fs = GDT_SELECTOR_PROC | 3;
  1140. m_scheduler_initialized = true;
  1141. asm volatile(
  1142. "movl %[new_esp], %%esp \n" // swich to new stack
  1143. "pushl %[from_to_thread] \n" // to_thread
  1144. "pushl %[from_to_thread] \n" // from_thread
  1145. "pushl $" __STRINGIFY(GDT_SELECTOR_CODE0) " \n"
  1146. "pushl %[new_eip] \n" // save the entry eip to the stack
  1147. "movl %%esp, %%ebx \n"
  1148. "addl $20, %%ebx \n" // calculate pointer to TrapFrame
  1149. "pushl %%ebx \n"
  1150. "cld \n"
  1151. "call enter_trap_no_irq \n"
  1152. "addl $4, %%esp \n"
  1153. "lret \n"
  1154. :: [new_esp] "g" (tss.esp),
  1155. [new_eip] "a" (tss.eip),
  1156. [from_to_thread] "b" (&initial_thread)
  1157. );
  1158. ASSERT_NOT_REACHED();
  1159. }
  1160. void Processor::enter_trap(TrapFrame& trap, bool raise_irq)
  1161. {
  1162. InterruptDisabler disabler;
  1163. trap.prev_irq_level = m_in_irq;
  1164. if (raise_irq)
  1165. m_in_irq++;
  1166. }
  1167. void Processor::exit_trap(TrapFrame& trap)
  1168. {
  1169. InterruptDisabler disabler;
  1170. ASSERT(m_in_irq >= trap.prev_irq_level);
  1171. m_in_irq = trap.prev_irq_level;
  1172. if (!m_in_irq && !m_in_critical)
  1173. check_invoke_scheduler();
  1174. }
  1175. void Processor::check_invoke_scheduler()
  1176. {
  1177. ASSERT(!m_in_irq);
  1178. ASSERT(!m_in_critical);
  1179. if (m_invoke_scheduler_async && m_scheduler_initialized) {
  1180. m_invoke_scheduler_async = false;
  1181. Scheduler::invoke_async();
  1182. }
  1183. }
  1184. void Processor::gdt_init()
  1185. {
  1186. m_gdt_length = 0;
  1187. m_gdtr.address = nullptr;
  1188. m_gdtr.limit = 0;
  1189. write_raw_gdt_entry(0x0000, 0x00000000, 0x00000000);
  1190. write_raw_gdt_entry(GDT_SELECTOR_CODE0, 0x0000ffff, 0x00cf9a00); // code0
  1191. write_raw_gdt_entry(GDT_SELECTOR_DATA0, 0x0000ffff, 0x00cf9200); // data0
  1192. write_raw_gdt_entry(GDT_SELECTOR_CODE3, 0x0000ffff, 0x00cffa00); // code3
  1193. write_raw_gdt_entry(GDT_SELECTOR_DATA3, 0x0000ffff, 0x00cff200); // data3
  1194. Descriptor tls_descriptor;
  1195. tls_descriptor.low = tls_descriptor.high = 0;
  1196. tls_descriptor.dpl = 3;
  1197. tls_descriptor.segment_present = 1;
  1198. tls_descriptor.granularity = 0;
  1199. tls_descriptor.zero = 0;
  1200. tls_descriptor.operation_size = 1;
  1201. tls_descriptor.descriptor_type = 1;
  1202. tls_descriptor.type = 2;
  1203. write_gdt_entry(GDT_SELECTOR_TLS, tls_descriptor); // tls3
  1204. Descriptor fs_descriptor;
  1205. fs_descriptor.set_base(this);
  1206. fs_descriptor.set_limit(sizeof(Processor));
  1207. fs_descriptor.dpl = 0;
  1208. fs_descriptor.segment_present = 1;
  1209. fs_descriptor.granularity = 0;
  1210. fs_descriptor.zero = 0;
  1211. fs_descriptor.operation_size = 1;
  1212. fs_descriptor.descriptor_type = 1;
  1213. fs_descriptor.type = 2;
  1214. write_gdt_entry(GDT_SELECTOR_PROC, fs_descriptor); // fs0
  1215. Descriptor tss_descriptor;
  1216. tss_descriptor.set_base(&m_tss);
  1217. tss_descriptor.set_limit(sizeof(TSS32));
  1218. tss_descriptor.dpl = 0;
  1219. tss_descriptor.segment_present = 1;
  1220. tss_descriptor.granularity = 0;
  1221. tss_descriptor.zero = 0;
  1222. tss_descriptor.operation_size = 1;
  1223. tss_descriptor.descriptor_type = 0;
  1224. tss_descriptor.type = 9;
  1225. write_gdt_entry(GDT_SELECTOR_TSS, tss_descriptor); // tss
  1226. flush_gdt();
  1227. load_task_register(GDT_SELECTOR_TSS);
  1228. asm volatile(
  1229. "mov %%ax, %%ds\n"
  1230. "mov %%ax, %%es\n"
  1231. "mov %%ax, %%gs\n"
  1232. "mov %%ax, %%ss\n" ::"a"(GDT_SELECTOR_DATA0)
  1233. : "memory");
  1234. set_fs(GDT_SELECTOR_PROC);
  1235. // Make sure CS points to the kernel code descriptor.
  1236. asm volatile(
  1237. "ljmpl $" __STRINGIFY(GDT_SELECTOR_CODE0) ", $sanity\n"
  1238. "sanity:\n");
  1239. }
  1240. void Processor::set_thread_specific(u8* data, size_t len)
  1241. {
  1242. auto& descriptor = get_gdt_entry(GDT_SELECTOR_TLS);
  1243. descriptor.set_base(data);
  1244. descriptor.set_limit(len);
  1245. }
  1246. }
  1247. #ifdef DEBUG
  1248. void __assertion_failed(const char* msg, const char* file, unsigned line, const char* func)
  1249. {
  1250. asm volatile("cli");
  1251. klog() << "ASSERTION FAILED: " << msg << "\n"
  1252. << file << ":" << line << " in " << func;
  1253. // Switch back to the current process's page tables if there are any.
  1254. // Otherwise stack walking will be a disaster.
  1255. auto process = Process::current();
  1256. if (process)
  1257. MM.enter_process_paging_scope(*process);
  1258. Kernel::dump_backtrace();
  1259. asm volatile("hlt");
  1260. for (;;)
  1261. ;
  1262. }
  1263. #endif
  1264. NonMaskableInterruptDisabler::NonMaskableInterruptDisabler()
  1265. {
  1266. IO::out8(0x70, IO::in8(0x70) | 0x80);
  1267. }
  1268. NonMaskableInterruptDisabler::~NonMaskableInterruptDisabler()
  1269. {
  1270. IO::out8(0x70, IO::in8(0x70) & 0x7F);
  1271. }