zig/std/os/zen.zig

232 lines
6.0 KiB
Zig
Raw Normal View History

2018-03-20 08:40:33 -07:00
//////////////////////////
//// IPC structures ////
//////////////////////////
2018-03-14 22:07:17 -07:00
pub const Message = struct {
2018-03-15 02:22:03 -07:00
sender: MailboxId,
receiver: MailboxId,
type: usize,
2018-03-15 02:22:03 -07:00
payload: usize,
2018-03-14 22:07:17 -07:00
pub fn from(mailbox_id: &const MailboxId) Message {
2018-03-14 22:07:17 -07:00
return Message {
.sender = MailboxId.Undefined,
2018-03-15 02:22:03 -07:00
.receiver = *mailbox_id,
.type = 0,
.payload = 0,
2018-03-14 22:07:17 -07:00
};
}
pub fn to(mailbox_id: &const MailboxId, msg_type: usize) Message {
return Message {
.sender = MailboxId.This,
.receiver = *mailbox_id,
.type = msg_type,
.payload = 0,
};
}
pub fn withData(mailbox_id: &const MailboxId, msg_type: usize, payload: usize) Message {
return Message {
.sender = MailboxId.This,
.receiver = *mailbox_id,
.type = msg_type,
.payload = payload,
};
}
2018-03-14 22:07:17 -07:00
};
pub const MailboxId = union(enum) {
Undefined,
2018-03-15 02:22:03 -07:00
This,
2018-03-14 22:07:17 -07:00
Kernel,
Port: u16,
2018-03-16 01:41:45 -07:00
Thread: u16,
2018-03-14 22:07:17 -07:00
};
2018-03-16 20:27:13 -07:00
//////////////////////////////////////
//// Ports reserved for servers ////
//////////////////////////////////////
2018-01-07 01:43:08 -08:00
2018-03-16 20:27:13 -07:00
pub const Server = struct {
pub const Keyboard = MailboxId { .Port = 0 };
pub const Terminal = MailboxId { .Port = 1 };
2018-03-15 02:22:03 -07:00
};
2018-01-07 01:43:08 -08:00
////////////////////////
//// POSIX things ////
////////////////////////
// Standard streams.
pub const STDIN_FILENO = 0;
pub const STDOUT_FILENO = 1;
pub const STDERR_FILENO = 2;
// FIXME: let's borrow Linux's error numbers for now.
pub const getErrno = @import("linux/index.zig").getErrno;
use @import("linux/errno.zig");
// TODO: implement this correctly.
pub fn read(fd: i32, buf: &u8, count: usize) usize {
switch (fd) {
STDIN_FILENO => {
var i: usize = 0;
while (i < count) : (i += 1) {
send(Message.to(Server.Keyboard, 0));
var message = Message.from(MailboxId.This);
receive(&message);
buf[i] = u8(message.payload);
}
},
else => unreachable,
}
return count;
}
// TODO: implement this correctly.
pub fn write(fd: i32, buf: &const u8, count: usize) usize {
switch (fd) {
STDOUT_FILENO, STDERR_FILENO => {
var i: usize = 0;
while (i < count) : (i += 1) {
send(Message.withData(Server.Terminal, 1, buf[i]));
}
},
else => unreachable,
}
return count;
}
2018-01-07 01:43:08 -08:00
///////////////////////////
//// Syscall numbers ////
///////////////////////////
2018-03-15 04:28:05 -07:00
pub const Syscall = enum(usize) {
2018-03-15 02:22:03 -07:00
exit = 0,
createPort = 1,
send = 2,
receive = 3,
2018-03-15 04:28:05 -07:00
subscribeIRQ = 4,
inb = 5,
map = 6,
createThread = 7,
2018-03-15 02:22:03 -07:00
};
2018-01-07 01:43:08 -08:00
////////////////////
//// Syscalls ////
////////////////////
pub fn exit(status: i32) noreturn {
2018-03-15 02:22:03 -07:00
_ = syscall1(Syscall.exit, @bitCast(usize, isize(status)));
2018-01-08 09:16:23 -08:00
unreachable;
}
2018-03-16 01:41:45 -07:00
pub fn createPort(mailbox_id: &const MailboxId) void {
_ = switch (*mailbox_id) {
MailboxId.Port => |id| syscall1(Syscall.createPort, id),
else => unreachable,
};
2018-01-07 01:43:08 -08:00
}
2018-03-14 22:07:17 -07:00
pub fn send(message: &const Message) void {
2018-03-15 02:22:03 -07:00
_ = syscall1(Syscall.send, @ptrToInt(message));
2018-01-07 01:43:08 -08:00
}
2018-03-14 22:07:17 -07:00
pub fn receive(destination: &Message) void {
2018-03-15 02:22:03 -07:00
_ = syscall1(Syscall.receive, @ptrToInt(destination));
2018-01-07 01:43:08 -08:00
}
2018-03-15 04:28:05 -07:00
pub fn subscribeIRQ(irq: u8, mailbox_id: &const MailboxId) void {
_ = syscall2(Syscall.subscribeIRQ, irq, @ptrToInt(mailbox_id));
}
pub fn inb(port: u16) u8 {
return u8(syscall1(Syscall.inb, port));
}
pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
2018-03-15 02:22:03 -07:00
return syscall4(Syscall.map, v_addr, p_addr, size, usize(writable)) != 0;
2018-01-07 01:43:08 -08:00
}
2018-01-29 07:57:27 -08:00
pub fn createThread(function: fn()void) u16 {
2018-03-15 02:22:03 -07:00
return u16(syscall1(Syscall.createThread, @ptrToInt(function)));
2018-01-08 09:16:23 -08:00
}
2018-01-07 01:43:08 -08:00
/////////////////////////
//// Syscall stubs ////
/////////////////////////
2018-03-15 04:28:05 -07:00
inline fn syscall0(number: Syscall) usize {
2018-01-07 01:43:08 -08:00
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number));
}
2018-03-15 04:28:05 -07:00
inline fn syscall1(number: Syscall, arg1: usize) usize {
2018-01-07 01:43:08 -08:00
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
[arg1] "{ecx}" (arg1));
}
2018-03-15 04:28:05 -07:00
inline fn syscall2(number: Syscall, arg1: usize, arg2: usize) usize {
2018-01-07 01:43:08 -08:00
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
[arg1] "{ecx}" (arg1),
[arg2] "{edx}" (arg2));
}
2018-03-15 04:28:05 -07:00
inline fn syscall3(number: Syscall, arg1: usize, arg2: usize, arg3: usize) usize {
2018-01-07 01:43:08 -08:00
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
[arg1] "{ecx}" (arg1),
[arg2] "{edx}" (arg2),
[arg3] "{ebx}" (arg3));
}
2018-03-15 04:28:05 -07:00
inline fn syscall4(number: Syscall, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
2018-01-07 01:43:08 -08:00
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
[arg1] "{ecx}" (arg1),
[arg2] "{edx}" (arg2),
[arg3] "{ebx}" (arg3),
[arg4] "{esi}" (arg4));
}
2018-03-15 04:28:05 -07:00
inline fn syscall5(number: Syscall, arg1: usize, arg2: usize, arg3: usize,
arg4: usize, arg5: usize) usize
2018-01-07 01:43:08 -08:00
{
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
[arg1] "{ecx}" (arg1),
[arg2] "{edx}" (arg2),
[arg3] "{ebx}" (arg3),
[arg4] "{esi}" (arg4),
[arg5] "{edi}" (arg5));
}
2018-03-09 22:24:52 -08:00
2018-03-15 04:28:05 -07:00
inline fn syscall6(number: Syscall, arg1: usize, arg2: usize, arg3: usize,
2018-03-09 22:24:52 -08:00
arg4: usize, arg5: usize, arg6: usize) usize
{
return asm volatile ("int $0x80"
: [ret] "={eax}" (-> usize)
: [number] "{eax}" (number),
[arg1] "{ecx}" (arg1),
[arg2] "{edx}" (arg2),
[arg3] "{ebx}" (arg3),
[arg4] "{esi}" (arg4),
[arg5] "{edi}" (arg5),
[arg6] "{ebp}" (arg6));
}