File src/kernel.cpp changed (mode: 100644) (index 34516d3..e9b80b5) |
... |
... |
extern "C" void stop(); |
116 |
116 |
|
|
117 |
117 |
static void heapDemo(MemoryManager &mm); |
static void heapDemo(MemoryManager &mm); |
118 |
118 |
static void ataDemo(); |
static void ataDemo(); |
119 |
|
static std::unique_ptr<NetworkStack> netDemo(GlobalDescriptorTable &gdt, |
|
120 |
|
TaskManager &taskManager, |
|
|
119 |
|
static std::unique_ptr<NetworkStack> netDemo(TaskManager &taskManager, |
121 |
120 |
drv::DriverManager &drvManager); |
drv::DriverManager &drvManager); |
122 |
121 |
static bool strEqual(const char s[], const char t[]); |
static bool strEqual(const char s[], const char t[]); |
123 |
122 |
|
|
|
... |
... |
kernelEntry(multiboot_info *multibootInfo, unsigned int /*multibootMagic*/) |
180 |
179 |
|
|
181 |
180 |
ataDemo(); |
ataDemo(); |
182 |
181 |
|
|
183 |
|
TaskManager taskManager; |
|
|
182 |
|
TaskManager taskManager(gdt); |
184 |
183 |
|
|
185 |
184 |
kprint("Initializing Hardware, Stage 3\n"); |
kprint("Initializing Hardware, Stage 3\n"); |
186 |
185 |
interrupts.activate(); |
interrupts.activate(); |
187 |
186 |
|
|
188 |
|
std::unique_ptr<NetworkStack> networkStack = netDemo(gdt, taskManager, |
|
|
187 |
|
std::unique_ptr<NetworkStack> networkStack = netDemo(taskManager, |
189 |
188 |
drvManager); |
drvManager); |
190 |
189 |
|
|
191 |
|
taskManager.addTask(std::unique_ptr<Task>(new Task(gdt, []() { |
|
|
190 |
|
taskManager.addTask(std::unique_ptr<Task>(new Task([]() { |
192 |
191 |
demo.run(); |
demo.run(); |
193 |
|
stop(); |
|
194 |
192 |
}))); |
}))); |
195 |
193 |
|
|
196 |
194 |
stop(); |
stop(); |
|
... |
... |
ataDemo() |
235 |
233 |
} |
} |
236 |
234 |
|
|
237 |
235 |
static std::unique_ptr<NetworkStack> |
static std::unique_ptr<NetworkStack> |
238 |
|
netDemo(GlobalDescriptorTable &gdt, TaskManager &taskManager, |
|
239 |
|
drv::DriverManager &drvManager) |
|
|
236 |
|
netDemo(TaskManager &taskManager, drv::DriverManager &drvManager) |
240 |
237 |
{ |
{ |
241 |
238 |
auto ourIP = toNetOrder<std::uint32_t>(0x0a00020f); // 10.0.2.15 |
auto ourIP = toNetOrder<std::uint32_t>(0x0a00020f); // 10.0.2.15 |
242 |
239 |
auto gatewayIP = toNetOrder<std::uint32_t>(0x0a000202); // 10.0.2.2 |
auto gatewayIP = toNetOrder<std::uint32_t>(0x0a000202); // 10.0.2.2 |
|
... |
... |
netDemo(GlobalDescriptorTable &gdt, TaskManager &taskManager, |
252 |
249 |
|
|
253 |
250 |
auto networkStack = new NetworkStack(net, gatewayIP, subnetMask); |
auto networkStack = new NetworkStack(net, gatewayIP, subnetMask); |
254 |
251 |
|
|
255 |
|
taskManager.addTask(std::unique_ptr<Task>(new Task(gdt, [=]() { |
|
|
252 |
|
taskManager.addTask(std::unique_ptr<Task>(new Task([=]() { |
256 |
253 |
net::UDPSocket &udpServer = networkStack->udp.listen(1234); |
net::UDPSocket &udpServer = networkStack->udp.listen(1234); |
257 |
254 |
networkStack->udp.bind(udpServer, &networkStack->udpHandler); |
networkStack->udp.bind(udpServer, &networkStack->udpHandler); |
258 |
255 |
|
|
|
... |
... |
netDemo(GlobalDescriptorTable &gdt, TaskManager &taskManager, |
263 |
260 |
udpClient.send(data); |
udpClient.send(data); |
264 |
261 |
}))); |
}))); |
265 |
262 |
|
|
266 |
|
taskManager.addTask(std::unique_ptr<Task>(new Task(gdt, [=]() { |
|
|
263 |
|
taskManager.addTask(std::unique_ptr<Task>(new Task([=]() { |
267 |
264 |
net::TCPSocket &tcpServer = networkStack->tcp.listen(1234); |
net::TCPSocket &tcpServer = networkStack->tcp.listen(1234); |
268 |
265 |
networkStack->tcp.bind(tcpServer, &networkStack->tcpHandler); |
networkStack->tcp.bind(tcpServer, &networkStack->tcpHandler); |
269 |
266 |
|
|
File src/multitasking.cpp changed (mode: 100644) (index b0f767a..fc290e9) |
... |
... |
extern "C" void taskEntryThunk(); |
6 |
6 |
extern "C" void taskEntry(Task *task); |
extern "C" void taskEntry(Task *task); |
7 |
7 |
void taskEntryCxx(Task *task); |
void taskEntryCxx(Task *task); |
8 |
8 |
|
|
9 |
|
CPUState * |
|
10 |
|
Task::makeCPUState(GlobalDescriptorTable &gdt) |
|
|
9 |
|
void |
|
10 |
|
Task::init(GlobalDescriptorTable &gdt) |
11 |
11 |
{ |
{ |
12 |
|
CPUState *cpuState = new(stack + sizeof(stack) - sizeof(CPUState)) CPUState; |
|
|
12 |
|
cpuState = new(stack + sizeof(stack) - sizeof(CPUState)) CPUState; |
13 |
13 |
|
|
14 |
14 |
cpuState->eax() = reinterpret_cast<std::uint32_t>(this); |
cpuState->eax() = reinterpret_cast<std::uint32_t>(this); |
15 |
15 |
cpuState->ebx() = 0; |
cpuState->ebx() = 0; |
|
... |
... |
Task::makeCPUState(GlobalDescriptorTable &gdt) |
30 |
30 |
cpuState->cs() = gdt.getCS(); |
cpuState->cs() = gdt.getCS(); |
31 |
31 |
// cpuState->ss() = ; |
// cpuState->ss() = ; |
32 |
32 |
cpuState->eflags() = 0x202; |
cpuState->eflags() = 0x202; |
33 |
|
|
|
34 |
|
return cpuState; |
|
35 |
33 |
} |
} |
36 |
34 |
|
|
37 |
35 |
void |
void |
|
... |
... |
void |
50 |
48 |
Task::entry() |
Task::entry() |
51 |
49 |
{ |
{ |
52 |
50 |
(*task)(); |
(*task)(); |
|
51 |
|
done = true; |
|
52 |
|
asm ("int $0x20"); |
53 |
53 |
} |
} |
54 |
54 |
|
|
55 |
|
TaskManager::TaskManager() |
|
56 |
|
: InterruptHandler(0x20), numTasks(0), currentTask(-1) |
|
|
55 |
|
TaskManager::TaskManager(GlobalDescriptorTable &gdt) |
|
56 |
|
: InterruptHandler(0x20), gdt(gdt), numTasks(0), currentTask(-1) |
57 |
57 |
{ |
{ |
58 |
58 |
} |
} |
59 |
59 |
|
|
|
... |
... |
TaskManager::addTask(std::unique_ptr<Task> task) |
63 |
63 |
if (numTasks == 256) { |
if (numTasks == 256) { |
64 |
64 |
return false; |
return false; |
65 |
65 |
} |
} |
|
66 |
|
|
|
67 |
|
task->init(gdt); |
66 |
68 |
tasks[numTasks++] = std::move(task); |
tasks[numTasks++] = std::move(task); |
67 |
69 |
return true; |
return true; |
68 |
70 |
} |
} |
|
... |
... |
TaskManager::schedule(CPUState *cpuState) |
83 |
85 |
|
|
84 |
86 |
if (currentTask >= 0) { |
if (currentTask >= 0) { |
85 |
87 |
tasks[currentTask]->cpuState = cpuState; |
tasks[currentTask]->cpuState = cpuState; |
|
88 |
|
if (tasks[currentTask]->done) { |
|
89 |
|
tasks[currentTask] = std::move(tasks[numTasks - 1]); |
|
90 |
|
--numTasks; |
|
91 |
|
currentTask %= numTasks; |
|
92 |
|
// XXX: this could be the last task, need to handle this. |
|
93 |
|
return tasks[currentTask]->cpuState; |
|
94 |
|
} |
86 |
95 |
} |
} |
87 |
96 |
|
|
88 |
97 |
if (++currentTask >= numTasks) { |
if (++currentTask >= numTasks) { |
File src/multitasking.hpp changed (mode: 100644) (index 5dafe33..65ba31b) |
... |
... |
class Task |
40 |
40 |
{ |
{ |
41 |
41 |
friend class TaskManager; |
friend class TaskManager; |
42 |
42 |
friend void taskEntryCxx(Task *task); |
friend void taskEntryCxx(Task *task); |
|
43 |
|
|
43 |
44 |
struct TaskImplBase |
struct TaskImplBase |
44 |
45 |
{ |
{ |
45 |
46 |
virtual ~TaskImplBase() = default; |
virtual ~TaskImplBase() = default; |
|
... |
... |
class Task |
64 |
65 |
|
|
65 |
66 |
public: |
public: |
66 |
67 |
template <typename F> |
template <typename F> |
67 |
|
Task(GlobalDescriptorTable &gdt, F &&f) |
|
68 |
|
: cpuState(makeCPUState(gdt)), task(new TaskImpl<F>(std::forward<F>(f))) |
|
|
68 |
|
Task(F &&f) |
|
69 |
|
: task(new TaskImpl<F>(std::forward<F>(f))), |
|
70 |
|
cpuState(nullptr), done(false) |
69 |
71 |
{ |
{ |
70 |
72 |
} |
} |
71 |
73 |
|
|
72 |
74 |
private: |
private: |
73 |
|
CPUState * makeCPUState(GlobalDescriptorTable &gdt); |
|
|
75 |
|
void init(GlobalDescriptorTable &gdt); |
74 |
76 |
void entry(); |
void entry(); |
75 |
77 |
|
|
76 |
78 |
private: |
private: |
|
... |
... |
private: |
78 |
80 |
std::uint64_t forceAlignment; |
std::uint64_t forceAlignment; |
79 |
81 |
std::uint8_t stack[4096]; // 4 KiB |
std::uint8_t stack[4096]; // 4 KiB |
80 |
82 |
}; |
}; |
81 |
|
CPUState *cpuState; |
|
82 |
83 |
std::unique_ptr<TaskImplBase> task; |
std::unique_ptr<TaskImplBase> task; |
|
84 |
|
CPUState *cpuState; |
|
85 |
|
bool done; |
83 |
86 |
}; |
}; |
84 |
87 |
|
|
85 |
88 |
class TaskManager : public hwcomm::InterruptHandler |
class TaskManager : public hwcomm::InterruptHandler |
86 |
89 |
{ |
{ |
|
90 |
|
friend void Task::entry(); |
|
91 |
|
|
87 |
92 |
public: |
public: |
88 |
|
TaskManager(); |
|
|
93 |
|
TaskManager(GlobalDescriptorTable &gdt); |
89 |
94 |
|
|
90 |
95 |
public: |
public: |
91 |
96 |
bool addTask(std::unique_ptr<Task> task); |
bool addTask(std::unique_ptr<Task> task); |
|
... |
... |
private: |
97 |
102 |
CPUState * schedule(CPUState *cpuState); |
CPUState * schedule(CPUState *cpuState); |
98 |
103 |
|
|
99 |
104 |
private: |
private: |
|
105 |
|
GlobalDescriptorTable &gdt; |
100 |
106 |
std::unique_ptr<Task> tasks[256]; |
std::unique_ptr<Task> tasks[256]; |
101 |
107 |
int numTasks; |
int numTasks; |
102 |
108 |
int currentTask; |
int currentTask; |