From 4fcf01adc57e35953aa9dde5006cf997c5b3518b Mon Sep 17 00:00:00 2001 From: Andrea Orru Date: Wed, 14 Mar 2018 22:07:17 -0700 Subject: [PATCH 1/8] IPC structure updates --- std/os/zen.zig | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/std/os/zen.zig b/std/os/zen.zig index b10b870d17..21e7d8f73e 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -1,19 +1,45 @@ +/////////////////////////// +//// IPC structures //// +/////////////////////////// + +pub const Message = struct { + from: MailboxId, + to: MailboxId, + payload: usize, + + pub fn from(mailbox_id: MailboxId) Message { + return Message { + .from = mailbox_id, + .to = undefined, + .payload = undefined, + }; + } +}; + +pub const MailboxId = union(enum) { + Me, + Kernel, + Port: u16, + //Thread: u16, +}; + + ////////////////////////////// //// Reserved mailboxes //// ////////////////////////////// -pub const MBOX_TERMINAL = 1; +pub const MBOX_TERMINAL = MailboxId { .Port = 0 }; /////////////////////////// //// Syscall numbers //// /////////////////////////// -pub const SYS_exit = 0; -pub const SYS_createMailbox = 1; -pub const SYS_send = 2; -pub const SYS_receive = 3; -pub const SYS_map = 4; +pub const SYS_exit = 0; +pub const SYS_createPort = 1; +pub const SYS_send = 2; +pub const SYS_receive = 3; +pub const SYS_map = 4; pub const SYS_createThread = 5; @@ -26,16 +52,16 @@ pub fn exit(status: i32) noreturn { unreachable; } -pub fn createMailbox(id: u16) void { - _ = syscall1(SYS_createMailbox, id); +pub fn createPort(id: u16) void { + _ = syscall1(SYS_createPort, id); } -pub fn send(mailbox_id: u16, data: usize) void { - _ = syscall2(SYS_send, mailbox_id, data); +pub fn send(message: &const Message) void { + _ = syscall1(SYS_send, @ptrToInt(message)); } -pub fn receive(mailbox_id: u16) usize { - return syscall1(SYS_receive, mailbox_id); +pub fn receive(destination: &Message) void { + _ = syscall1(SYS_receive, @ptrToInt(destination)); } pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool { From 9b7e4b535c87c32d81fab88b92c967b04188212f Mon Sep 17 00:00:00 2001 From: Andrea Orru Date: Thu, 15 Mar 2018 02:22:03 -0700 Subject: [PATCH 2/8] More precise naming --- std/os/zen.zig | 67 +++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/std/os/zen.zig b/std/os/zen.zig index 21e7d8f73e..7d054a0e4f 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -3,44 +3,49 @@ /////////////////////////// pub const Message = struct { - from: MailboxId, - to: MailboxId, - payload: usize, + sender: MailboxId, + receiver: MailboxId, + payload: usize, - pub fn from(mailbox_id: MailboxId) Message { + pub fn withReceiver(mailbox_id: &const MailboxId) Message { return Message { - .from = mailbox_id, - .to = undefined, - .payload = undefined, + .sender = undefined, + .receiver = *mailbox_id, + .payload = undefined, }; } }; pub const MailboxId = union(enum) { - Me, + This, Kernel, Port: u16, //Thread: u16, }; -////////////////////////////// -//// Reserved mailboxes //// -////////////////////////////// +/////////////////////////////////////// +//// Ports reserved for services //// +/////////////////////////////////////// -pub const MBOX_TERMINAL = MailboxId { .Port = 0 }; +pub const Service = struct { + pub const Terminal = MailboxId { .Port = 0 }; + pub const Keyboard = MailboxId { .Port = 1 }; +}; /////////////////////////// //// Syscall numbers //// /////////////////////////// -pub const SYS_exit = 0; -pub const SYS_createPort = 1; -pub const SYS_send = 2; -pub const SYS_receive = 3; -pub const SYS_map = 4; -pub const SYS_createThread = 5; +pub const Syscall = enum { + exit = 0, + createPort = 1, + send = 2, + receive = 3, + map = 4, + createThread = 5, +}; //////////////////// @@ -48,28 +53,28 @@ pub const SYS_createThread = 5; //////////////////// pub fn exit(status: i32) noreturn { - _ = syscall1(SYS_exit, @bitCast(usize, isize(status))); + _ = syscall1(Syscall.exit, @bitCast(usize, isize(status))); unreachable; } pub fn createPort(id: u16) void { - _ = syscall1(SYS_createPort, id); + _ = syscall1(Syscall.createPort, id); } pub fn send(message: &const Message) void { - _ = syscall1(SYS_send, @ptrToInt(message)); + _ = syscall1(Syscall.send, @ptrToInt(message)); } pub fn receive(destination: &Message) void { - _ = syscall1(SYS_receive, @ptrToInt(destination)); + _ = syscall1(Syscall.receive, @ptrToInt(destination)); } pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool { - return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0; + return syscall4(Syscall.map, v_addr, p_addr, size, usize(writable)) != 0; } pub fn createThread(function: fn()void) u16 { - return u16(syscall1(SYS_createThread, @ptrToInt(function))); + return u16(syscall1(Syscall.createThread, @ptrToInt(function))); } @@ -77,20 +82,20 @@ pub fn createThread(function: fn()void) u16 { //// Syscall stubs //// ///////////////////////// -pub inline fn syscall0(number: usize) usize { +inline fn syscall0(number: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number)); } -pub inline fn syscall1(number: usize, arg1: usize) usize { +inline fn syscall1(number: usize, arg1: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number), [arg1] "{ecx}" (arg1)); } -pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize { +inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number), @@ -98,7 +103,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize { [arg2] "{edx}" (arg2)); } -pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { +inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number), @@ -107,7 +112,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usi [arg3] "{ebx}" (arg3)); } -pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { +inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number), @@ -117,7 +122,7 @@ pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg [arg4] "{esi}" (arg4)); } -pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, +inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { return asm volatile ("int $0x80" @@ -130,7 +135,7 @@ pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, [arg5] "{edi}" (arg5)); } -pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, +inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize, arg6: usize) usize { return asm volatile ("int $0x80" From 681c62941e9219b475c2e441e360c0c72cd6ccdc Mon Sep 17 00:00:00 2001 From: Andrea Orru Date: Thu, 15 Mar 2018 04:28:05 -0700 Subject: [PATCH 3/8] subscribeIRQ support --- std/os/zen.zig | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/std/os/zen.zig b/std/os/zen.zig index 7d054a0e4f..94d470d70f 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -38,13 +38,15 @@ pub const Service = struct { //// Syscall numbers //// /////////////////////////// -pub const Syscall = enum { +pub const Syscall = enum(usize) { exit = 0, createPort = 1, send = 2, receive = 3, - map = 4, - createThread = 5, + subscribeIRQ = 4, + inb = 5, + map = 6, + createThread = 7, }; @@ -69,6 +71,14 @@ pub fn receive(destination: &Message) void { _ = syscall1(Syscall.receive, @ptrToInt(destination)); } +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 { return syscall4(Syscall.map, v_addr, p_addr, size, usize(writable)) != 0; } @@ -82,20 +92,20 @@ pub fn createThread(function: fn()void) u16 { //// Syscall stubs //// ///////////////////////// -inline fn syscall0(number: usize) usize { +inline fn syscall0(number: Syscall) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number)); } -inline fn syscall1(number: usize, arg1: usize) usize { +inline fn syscall1(number: Syscall, arg1: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number), [arg1] "{ecx}" (arg1)); } -inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize { +inline fn syscall2(number: Syscall, arg1: usize, arg2: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number), @@ -103,7 +113,7 @@ inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize { [arg2] "{edx}" (arg2)); } -inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { +inline fn syscall3(number: Syscall, arg1: usize, arg2: usize, arg3: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number), @@ -112,7 +122,7 @@ inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { [arg3] "{ebx}" (arg3)); } -inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { +inline fn syscall4(number: Syscall, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { return asm volatile ("int $0x80" : [ret] "={eax}" (-> usize) : [number] "{eax}" (number), @@ -122,7 +132,7 @@ inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: u [arg4] "{esi}" (arg4)); } -inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, +inline fn syscall5(number: Syscall, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { return asm volatile ("int $0x80" @@ -135,7 +145,7 @@ inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, [arg5] "{edi}" (arg5)); } -inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, +inline fn syscall6(number: Syscall, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize, arg6: usize) usize { return asm volatile ("int $0x80" From 4c16deed3ef4f3c4695deb32a6e7c1174bd38bd9 Mon Sep 17 00:00:00 2001 From: Andrea Orru Date: Thu, 15 Mar 2018 17:57:56 -0700 Subject: [PATCH 4/8] Some POSIX stuff, including a primitive write --- std/os/zen.zig | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/std/os/zen.zig b/std/os/zen.zig index 94d470d70f..37c674c9e1 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -7,13 +7,21 @@ pub const Message = struct { receiver: MailboxId, payload: usize, - pub fn withReceiver(mailbox_id: &const MailboxId) Message { + pub fn from(mailbox_id: &const MailboxId) Message { return Message { .sender = undefined, .receiver = *mailbox_id, .payload = undefined, }; } + + pub fn to(mailbox_id: &const MailboxId, payload: usize) Message { + return Message { + .sender = MailboxId.This, + .receiver = *mailbox_id, + .payload = payload, + }; + } }; pub const MailboxId = union(enum) { @@ -29,11 +37,40 @@ pub const MailboxId = union(enum) { /////////////////////////////////////// pub const Service = struct { - pub const Terminal = MailboxId { .Port = 0 }; - pub const Keyboard = MailboxId { .Port = 1 }; + pub const Keyboard = MailboxId { .Port = 0 }; + pub const Terminal = MailboxId { .Port = 1 }; }; +//////////////////////// +//// 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 write(fd: i32, buf: &const u8, count: usize) usize { + switch (fd) { + STDIN_FILENO => unreachable, + STDOUT_FILENO, STDERR_FILENO => { + var i: usize = 0; + while (i < count) : (i += 1) { + send(Message.to(Service.Terminal, buf[i])); + } + }, + else => unreachable, + } + return count; +} + + /////////////////////////// //// Syscall numbers //// /////////////////////////// From 81941f91611adb33796b846f492f1073b4ab9d31 Mon Sep 17 00:00:00 2001 From: Andrea Orru Date: Fri, 16 Mar 2018 01:41:45 -0700 Subject: [PATCH 5/8] Add Thread option for Mailboxes --- std/os/zen.zig | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/std/os/zen.zig b/std/os/zen.zig index 37c674c9e1..814ec36884 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -28,7 +28,7 @@ pub const MailboxId = union(enum) { This, Kernel, Port: u16, - //Thread: u16, + Thread: u16, }; @@ -96,8 +96,11 @@ pub fn exit(status: i32) noreturn { unreachable; } -pub fn createPort(id: u16) void { - _ = syscall1(Syscall.createPort, id); +pub fn createPort(mailbox_id: &const MailboxId) void { + _ = switch (*mailbox_id) { + MailboxId.Port => |id| syscall1(Syscall.createPort, id), + else => unreachable, + }; } pub fn send(message: &const Message) void { From df3d2115b5e45eefb3898d89307b05505c2f5b5a Mon Sep 17 00:00:00 2001 From: Andrea Orru Date: Fri, 16 Mar 2018 20:27:13 -0700 Subject: [PATCH 6/8] Service -> Server --- std/os/zen.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/std/os/zen.zig b/std/os/zen.zig index 814ec36884..b1a904a7c1 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -32,11 +32,11 @@ pub const MailboxId = union(enum) { }; -/////////////////////////////////////// -//// Ports reserved for services //// -/////////////////////////////////////// +////////////////////////////////////// +//// Ports reserved for servers //// +////////////////////////////////////// -pub const Service = struct { +pub const Server = struct { pub const Keyboard = MailboxId { .Port = 0 }; pub const Terminal = MailboxId { .Port = 1 }; }; @@ -62,7 +62,7 @@ pub fn write(fd: i32, buf: &const u8, count: usize) usize { STDOUT_FILENO, STDERR_FILENO => { var i: usize = 0; while (i < count) : (i += 1) { - send(Message.to(Service.Terminal, buf[i])); + send(Message.to(Server.Terminal, buf[i])); } }, else => unreachable, From 935f10502f9308b262c3d4b979a3fbe20baf670f Mon Sep 17 00:00:00 2001 From: Andrea Orru Date: Sun, 18 Mar 2018 14:45:23 -0400 Subject: [PATCH 7/8] Message type, Undefined mailbox, read syscall, more constructors --- std/os/zen.zig | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/std/os/zen.zig b/std/os/zen.zig index b1a904a7c1..9777807424 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -5,26 +5,39 @@ pub const Message = struct { sender: MailboxId, receiver: MailboxId, + type: usize, payload: usize, pub fn from(mailbox_id: &const MailboxId) Message { return Message { - .sender = undefined, + .sender = MailboxId.Undefined, .receiver = *mailbox_id, - .payload = undefined, + .type = 0, + .payload = 0, }; } - pub fn to(mailbox_id: &const MailboxId, payload: usize) Message { + 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, }; } }; pub const MailboxId = union(enum) { + Undefined, This, Kernel, Port: u16, @@ -55,14 +68,32 @@ pub const STDERR_FILENO = 2; 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) { - STDIN_FILENO => unreachable, STDOUT_FILENO, STDERR_FILENO => { var i: usize = 0; while (i < count) : (i += 1) { - send(Message.to(Server.Terminal, buf[i])); + send(Message.withData(Server.Terminal, 1, buf[i])); } }, else => unreachable, From 0082ed0ef1415d9c972348aae136b5684838c983 Mon Sep 17 00:00:00 2001 From: Andrea Orru Date: Tue, 20 Mar 2018 11:40:33 -0400 Subject: [PATCH 8/8] Public SplitIterator --- std/mem.zig | 2 +- std/os/zen.zig | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/std/mem.zig b/std/mem.zig index 07521bfcb8..97cb35ae65 100644 --- a/std/mem.zig +++ b/std/mem.zig @@ -354,7 +354,7 @@ pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle); } -const SplitIterator = struct { +pub const SplitIterator = struct { buffer: []const u8, split_bytes: []const u8, index: usize, diff --git a/std/os/zen.zig b/std/os/zen.zig index 9777807424..9e1944dc6d 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -1,6 +1,6 @@ -/////////////////////////// -//// IPC structures //// -/////////////////////////// +////////////////////////// +//// IPC structures //// +////////////////////////// pub const Message = struct { sender: MailboxId,