| 71 | } |
| 72 | |
| 73 | void InitializeCPU(uint16_t id){ |
| 74 | CPU* cpu = new CPU; |
| 75 | cpu->id = id; |
| 76 | cpu->runQueueLock = 0; |
| 77 | cpus[id] = cpu; |
| 78 | |
| 79 | *smpMagic = 0; // Set magic to 0 |
| 80 | *smpID = id; // Set ID to our CPU's ID |
| 81 | *smpEntry2 = (uint64_t)SMPEntry; // Our second entry point |
| 82 | *smpStack = (uint64_t)Memory::KernelAllocate4KPages(1); // 4K stack |
| 83 | Memory::KernelMapVirtualMemory4K(Memory::AllocatePhysicalMemoryBlock(), *smpStack, 1); |
| 84 | *smpStack += PAGE_SIZE_4K; |
| 85 | *smpGDT = GDT64Pointer64; |
| 86 | |
| 87 | asm volatile("mov %%cr3, %%rax" : "=a"(*smpCR3)); |
| 88 | |
| 89 | APIC::Local::SendIPI(id, ICR_DSH_DEST, ICR_MESSAGE_TYPE_INIT, 0); |
| 90 | |
| 91 | wait(20); |
| 92 | |
| 93 | if((*smpMagic) != 0xB33F){ // Check if the trampoline code set the flag to let us know it has started |
| 94 | APIC::Local::SendIPI(id, ICR_DSH_DEST, ICR_MESSAGE_TYPE_STARTUP, (SMP_TRAMPOLINE_ENTRY >> 12)); |
| 95 | |
| 96 | wait(80); |
| 97 | } |
| 98 | |
| 99 | if((*smpMagic) != 0xB33F){ |
| 100 | wait(100); |
| 101 | } |
| 102 | |
| 103 | if((*smpMagic) != 0xB33F){ |
| 104 | Log::Error("[SMP] Failed to start CPU #%d", id); |
| 105 | return; |
| 106 | } |
| 107 | |
| 108 | while(!doneInit); |
| 109 | |
| 110 | doneInit = false; |
| 111 | } |
| 112 | |
| 113 | void Initialize(){ |
| 114 | cpus[0] = new CPU; // Initialize CPU 0 |
no test coverage detected