celtic / akari

My attempt at bringing light to operating system development.

akari / UserCalls.cpp
100644 94 lines (75 sloc) 2.208 kb
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <UserCalls.hpp>
#include <Akari.hpp>
#include <POSIX.hpp>
#include <Symbol.hpp>
#include <debug.hpp>
#include <Console.hpp>
#include <Tasks.hpp>
#include <Syscall.hpp>
#include <BlockingCall.hpp>
 
namespace User {
void putc(char c) {
Akari->console->putChar(c);
}
 
void puts(const char *s) {
Akari->console->putString(s);
}
 
void putl(u32 n, u8 base) {
Akari->console->putInt(n, base);
}
u32 getProcessId() {
return Akari->tasks->current->id;
}
 
void irqWait() {
if (Akari->tasks->current->irqListenHits == 0) {
Akari->tasks->current->irqWaiting = true;
 
Akari->syscall->returnToNextTask();
return;
}
 
Akari->tasks->current->irqListenHits--;
}
 
void irqListen(u32 irq) {
Akari->tasks->current->irqListen = irq;
Akari->tasks->current->irqListenHits = 0;
}
 
 
void panic(const char *s) {
// TODO: check permission. should be ring 1 or 0, but at least definitely not 3.
// even ring 1 tasks should be able to die and come back up. that's the point, right?
// so ring 1 tasks panicking should, like ring 3 ones, just be killed off. (and
// the idea is that the system notes this and fixes it. yep) (TODO!)
AkariPanic(s);
}
 
void exit() {
Akari->syscall->returnToNextTask();
// Find the Task* which refers to Akari->tasks->current, and get it to skip it.
Tasks::Task **scanner = &Akari->tasks->start;
while (*scanner != Akari->tasks->current) {
scanner = &(*scanner)->next;
}
 
Akari->console->putString("exit(): 0x");
Akari->console->putInt((u32)*scanner, 16);
Akari->console->putString(" -> 0x");
Akari->console->putInt((u32)(*scanner)->next, 16);
Akari->console->putString("\n");
 
*scanner = (*scanner)->next;
// Gone! XXX what happens when the last task exists!? Everything probably goes to hell ...
}
 
void defer() {
Akari->syscall->returnToNextTask();
}
 
void *malloc(u32 n) {
ASSERT(Akari->tasks->current->heap);
return Akari->tasks->current->heap->alloc(n);
}
 
void free(void *p) {
ASSERT(Akari->tasks->current->heap);
// TODO! :-)
}
 
void *memcpy(void *dest, const void *src, u32 n) {
char *w = (char *)dest;
const char *r = (const char *)src;
 
while (n--)
*w++ = *r++;
return dest;
}
}