summaryrefslogtreecommitdiffstats
path: root/src/kernel/cpumgr.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/cpumgr.C')
-rw-r--r--src/kernel/cpumgr.C109
1 files changed, 69 insertions, 40 deletions
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C
index 4fdc8fde9..48bf4a5e8 100644
--- a/src/kernel/cpumgr.C
+++ b/src/kernel/cpumgr.C
@@ -36,8 +36,10 @@
#include <kernel/cpuid.H>
#include <kernel/ptmgr.H>
#include <kernel/heapmgr.H>
+#include <kernel/intmsghandler.H>
+#include <errno.h>
-cpu_t* CpuManager::cv_cpus[CpuManager::MAXCPUS] = { NULL };
+cpu_t** CpuManager::cv_cpus = NULL;
bool CpuManager::cv_shutdown_requested = false;
uint64_t CpuManager::cv_shutdown_status = 0;
Barrier CpuManager::cv_barrier;
@@ -49,16 +51,11 @@ InteractiveDebug CpuManager::cv_interactive_debug;
CpuManager::CpuManager()
{
for (int i = 0; i < MAXCPUS; i++)
- cv_cpus[i] = NULL;
+ cv_cpus[i] = NULL;
memset(&cv_interactive_debug, '\0', sizeof(cv_interactive_debug));
}
-cpu_t* CpuManager::getCurrentCPU()
-{
- return cv_cpus[getPIR()];
-}
-
cpu_t* CpuManager::getMasterCPU()
{
for (int i = 0; i < MAXCPUS; i++)
@@ -77,27 +74,13 @@ void CpuManager::init()
// enter the kernel, so we skip initializing all the other CPUs for now.
// Determine number of threads on this core.
- size_t threads = -1;
- switch (CpuID::getCpuType())
- {
- case CORE_POWER7:
- case CORE_POWER7_PLUS:
- threads = 4;
- break;
-
- case CORE_POWER8_VENICE:
- case CORE_POWER8_MURANO:
- threads = 8;
- break;
+ size_t threads = getThreadCount();
- case CORE_UNKNOWN:
- default:
- kassert(false);
- break;
- }
+ // Set up CPU structure.
+ cv_cpus = new cpu_t*[MAXCPUS];
// Create CPU objects starting at the thread-0 for this core.
- size_t baseCpu = getPIR() & ~(threads-1);
+ size_t baseCpu = getCpuId() & ~(threads-1);
for (size_t i = 0; i < threads; i++)
Singleton<CpuManager>::instance().startCPU(i + baseCpu);
}
@@ -119,22 +102,22 @@ void CpuManager::startCPU(ssize_t i)
bool currentCPU = false;
if (i < 0)
{
- i = getCpuId();
- currentCPU = true;
+ i = getCpuId();
+ currentCPU = true;
}
else if (getCpuId() == (uint64_t)i)
{
- currentCPU = true;
+ currentCPU = true;
}
// Initialize CPU structure.
if (NULL == cv_cpus[i])
{
- printk("Starting CPU %ld...", i);
- cpu_t* cpu = cv_cpus[i] = new cpu_t;
+ printk("Starting CPU %ld...", i);
+ cpu_t* cpu = cv_cpus[i] = new cpu_t;
- // Initialize CPU.
- cpu->cpu = i;
+ // Initialize CPU.
+ cpu->cpu = i;
if (currentCPU)
{
cpu->master = true;
@@ -143,18 +126,21 @@ void CpuManager::startCPU(ssize_t i)
{
cpu->master = false;
}
- cpu->scheduler = &Singleton<Scheduler>::instance();
+ cpu->scheduler = &Singleton<Scheduler>::instance();
cpu->scheduler_extra = NULL;
- cpu->kernel_stack =
- (void*) (((uint64_t)PageManager::allocatePage(4)) + 16320);
+ cpu->kernel_stack =
+ (void*) (((uint64_t)PageManager::allocatePage(4)) + 16320);
cpu->xscom_mutex = (mutex_t)MUTEX_INITIALIZER;
- // Create idle task.
- cpu->idle_task = TaskManager::createIdleTask();
- cpu->idle_task->cpu = cpu;
+ // Create idle task.
+ cpu->idle_task = TaskManager::createIdleTask();
+ cpu->idle_task->cpu = cpu;
cpu->periodic_count = 0;
- printk("done\n");
+ // Call TimeManager setup for a CPU.
+ TimeManager::init_cpu(cpu);
+
+ printk("done\n");
}
if (currentCPU)
@@ -176,7 +162,7 @@ void CpuManager::startSlaveCPU(cpu_t* cpu)
void CpuManager::activateCPU(cpu_t * i_cpu)
{
i_cpu->active = true;
- __sync_fetch_and_add(&cv_cpuCount, 1);
+ __sync_add_and_fetch(&cv_cpuCount, 1);
lwsync();
}
@@ -247,6 +233,49 @@ void CpuManager::executePeriodics(cpu_t * i_cpu)
}
}
+int CpuManager::startCore(uint64_t pir)
+{
+ size_t threads = getThreadCount();
+ pir = pir & ~(threads-1);
+
+
+ if (pir >= MAXCPUS) { return -ENXIO; }
+
+ for(size_t i = 0; i < threads; i++)
+ {
+ Singleton<CpuManager>::instance().startCPU(pir + i);
+ }
+ __sync_synchronize();
+
+ InterruptMsgHdlr::addCpuCore(pir);
+
+ return 0;
+};
+
+size_t CpuManager::getThreadCount()
+{
+ size_t threads = 0;
+ switch (CpuID::getCpuType())
+ {
+ case CORE_POWER7:
+ case CORE_POWER7_PLUS:
+ threads = 4;
+ break;
+
+ case CORE_POWER8_VENICE:
+ case CORE_POWER8_MURANO:
+ threads = 8;
+ break;
+
+ case CORE_UNKNOWN:
+ default:
+ kassert(false);
+ break;
+ }
+
+ return threads;
+}
+
void CpuManager::forceMemoryPeriodic()
{
cv_forcedMemPeriodic = true;
OpenPOWER on IntegriCloud