#include #include #include #include #include #include #include #include #include #include cpu_t* CpuManager::cv_cpus[CpuManager::MAXCPUS] = { NULL }; CpuManager::CpuManager() { for (int i = 0; i < MAXCPUS; i++) cv_cpus[i] = NULL; } cpu_t* CpuManager::getCurrentCPU() { register task_t* current_task = (task_t*) getSPRG3(); return current_task->cpu; } void CpuManager::init() { for (int i = 0; i < KERNEL_MAX_SUPPORTED_CPUS; i++) Singleton::instance().startCPU(i); } void CpuManager::init_slave_smp(cpu_t* cpu) { Singleton::instance().startSlaveCPU(cpu); } void CpuManager::startCPU(ssize_t i) { bool currentCPU = false; if (i < 0) { i = getCpuId(); currentCPU = true; } else if (getCpuId() == (uint64_t)i) { currentCPU = true; } // Initialize CPU structure. if (NULL == cv_cpus[i]) { printk("Starting CPU %ld...", i); cpu_t* cpu = cv_cpus[i] = new cpu_t; // Initialize CPU. cpu->cpu = i; cpu->scheduler = &Singleton::instance(); cpu->kernel_stack = (void*) (((uint64_t)PageManager::allocatePage(4)) + 16320); // Create idle task. cpu->idle_task = TaskManager::createIdleTask(); cpu->idle_task->cpu = cpu; printk("done\n"); } if (currentCPU) { setSPRG3((uint64_t) cv_cpus[i]->idle_task); register uint64_t decrementer = TimeManager::getTimeSliceCount(); asm volatile("mtdec %0" :: "r"(decrementer)); } return; } void CpuManager::startSlaveCPU(cpu_t* cpu) { setSPRG3((uint64_t) cpu->idle_task); register uint64_t decrementer = TimeManager::getTimeSliceCount(); asm volatile("mtdec %0" :: "r"(decrementer)); return; } uint64_t isCPU0() { return (0 == getCpuId()); }