blob: d43b28ca802626e7936b4298a0269f24a09ea5a5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#include <kernel/cpumgr.H>
#include <kernel/task.H>
#include <kernel/cpu.H>
#include <kernel/scheduler.H>
#include <kernel/taskmgr.H>
#include <kernel/pagemgr.H>
#include <kernel/console.H>
#include <util/singleton.H>
CpuManager::CpuManager()
{
for (int i = 0; i < MAXCPUS; i++)
iv_cpus[i] = NULL;
}
cpu_t* CpuManager::getCurrentCPU()
{
register task_t* current_task = NULL;
asm volatile("mfsprg3 %0" : "=r" (current_task) );
return current_task->cpu;
}
void CpuManager::init()
{
Singleton<CpuManager>::instance().startCPU();
}
void CpuManager::startCPU(ssize_t i)
{
bool currentCPU = false;
if (i < 0)
{
// TODO: Determine position of this CPU, somehow.
i = 0;
currentCPU = true;
}
printk("Starting CPU %d...", i);
// Initialize CPU structure.
if (NULL == iv_cpus[i])
{
cpu_t* cpu = iv_cpus[i] = new cpu_t;
// Initialize CPU.
cpu->cpu = i;
cpu->scheduler = new Scheduler(cpu);
cpu->kernel_stack =
(void*) (((uint64_t)PageManager::allocatePage(4)) + 16320);
// Create idle task.
task_t * idle_task = TaskManager::createIdleTask();
idle_task->cpu = cpu;
// Add to scheduler.
cpu->scheduler->setIdleTask(idle_task);
}
if (currentCPU)
{
register task_t* idle_task = iv_cpus[i]->scheduler->getIdleTask();
asm volatile("mtsprg3 %0" :: "r" (idle_task));
// TODO: Set up decrementer properly.
register uint64_t decrementer = 0x0f000000;
asm volatile("mtdec %0" :: "r"(decrementer));
}
else
{
// TODO once we get to SMP.
}
printk("done\n");
return;
}
|